Rev Author Line No. Line
178 kaklik 1 namespace mimas {
2  
3 template< typename T >
4 image_dc1394input< T >::image_dc1394input( const char *device,
5 int node,
6 int channel,
7 int preferredFormat,
8 int preferredMode,
9 int preferredFormat7Colour,
10 int speed )
11 throw (mimasexception):
12 m_device(device), m_cameraNode(NULL), m_node(-1), m_handle(NULL),
13 m_format(-1), m_mode(-1), m_format7Colour(-1),
14 m_colourSpace(Unknown), m_frameRate(-1), m_bufferUsed( false )
15 {
16 try {
17 m_handle = dc1394_create_handle( 0 );
18 MMERROR( m_handle != NULL, mimasexception, ,
19 "Unable to acquire raw1394 handle. Please check, wether "
20 "the kernel modules 'ieee1394','raw1394' and 'ohci1394' "
21 "are loaded and wether you have read/write permission on "
22 "\"/dev/raw1394\"." );
23  
24 int numNodes = raw1394_get_nodecount(m_handle);
25 int numCameras;
26 #ifndef NDEBUG
27 m_cameraNode =
28 dc1394_get_camera_nodes( m_handle, &numCameras, 1 );
29 #else
30 m_cameraNode =
31 dc1394_get_camera_nodes( m_handle, &numCameras, 0 );
32 #endif
33 MMERROR( numCameras >= 0, mimasexception, ,
34 "Failed to acquire list of digital camera nodes." );
35 MMERROR( numCameras >= 1, mimasexception, , "Did not find a single digital "
36 "camera on the firewire bus." );
37  
38 // Check for iso-transfer bug of old raw1394 system
39 // (before kernel 2.4.21-pre2).
40 // Compare http://sourceforge.net/tracker/index.php?func=detail&aid=435107&group_id=8157&atid=108157
41 for ( int i=0; i<numCameras; i++ ) {
42 MMERROR( m_cameraNode[i] != numNodes - 1, mimasexception, ,
43 "A digital camera has become the root-node of the "
44 "firewire bus. Try to fix this problem by reloading the "
45 "'ohci1394'-module with option 'attempt_root=1'." );
46 };
47  
48 MMERROR( node >= 0 && node < numCameras, mimasexception, ,
49 "Camera-node number " << node << " out of range. The "
50 "range is [ 0; " << numCameras << " )." );
51  
52 MMERROR( dc1394_camera_on( m_handle, node ), mimasexception, ,
53 "Could not switch on camera" );
54 m_node = node;
55 selectFormat( preferredFormat );
56 selectMode( preferredMode );
57  
58 if ( m_mode >= MODE_FORMAT7_MIN && m_mode <= MODE_FORMAT7_MAX ) {
59 selectFormat7Colour( preferredFormat7Colour );
60 // Setup DMA capture (allocates ringbuffer).
61 MMERROR( dc1394_dma_setup_format7_capture
62 ( m_handle, m_cameraNode[ m_node ], channel,
63 m_mode, speed, QUERY_FROM_CAMERA,
64 (unsigned int)QUERY_FROM_CAMERA,
65 (unsigned int)QUERY_FROM_CAMERA,
66 (unsigned int)QUERY_FROM_CAMERA,
67 (unsigned int)QUERY_FROM_CAMERA,
68 4,// Number of dma-buffers.
69 1,// Drop frames.
70 m_device.empty() ? (const char *)NULL : device,
71 &m_camera ) == DC1394_SUCCESS,
72 mimasexception, ,
73 "Error setting up format7 DMA capture. Please check, wether "
74 "the kernel modules 'video1394' is loaded and wether "
75 "you have read/write permission on \"/dev/video1394/*\"" );
76 } else {
77 selectFrameRate( -1 );
78 // Setup DMA capture (allocates ringbuffer).
79 MMERROR( dc1394_dma_setup_capture
80 ( m_handle, m_cameraNode[ m_node ], channel,
81 m_format, m_mode, speed, m_frameRate,
82 4,// Number of dma-buffers.
83 #ifdef LIBDC1394_OLD
84 0,// Extra-buffering (?)
85 #endif
86 1,// Drop frames.
87 m_device.empty() ? (const char *)NULL : device,
88 &m_camera ) == DC1394_SUCCESS,
89 mimasexception, ,
90 "Error setting up DMA capture. Please check, wether "
91 "the kernel modules 'video1394' is loaded and wether "
92 "you have read/write permission on \"/dev/video1394/*\"" );
93 };
94  
95 // Start capture.
96 MMERROR( dc1394_start_iso_transmission( m_handle, m_camera.node )
97 == DC1394_SUCCESS, mimasexception, ,
98 "Error starting camera iso transmission." );
99  
100 } catch ( mimasexception &e ) {
101  
102 if ( m_node != -1 ) dc1394_camera_off( m_handle, m_node );
103 if ( m_cameraNode != NULL ) dc1394_free_camera_nodes( m_cameraNode );
104 if ( m_handle != NULL ) dc1394_destroy_handle( m_handle );
105 throw e;
106  
107 };
108 }
109  
110 template< typename T >
111 image_dc1394input< T >::~image_dc1394input(void)
112 {
113 if ( m_handle != NULL ) close();
114 }
115  
116 template< typename T >
117 void image_dc1394input< T >::close(void)
118 {
119 if ( m_bufferUsed ) {
120 dc1394_dma_done_with_buffer( &m_camera );
121 m_bufferUsed = false;
122 };
123 if ( m_handle != NULL ) {
124 // Halt iso reception.
125 dc1394_dma_unlisten( m_handle, &m_camera );
126 // Stop iso transmission.
127 dc1394_stop_iso_transmission( m_handle, m_camera.node );
128 // Free mapped memory.
129 dc1394_dma_release_camera( m_handle, &m_camera );
130 // Free list of nodes.
131 dc1394_free_camera_nodes( m_cameraNode ); m_cameraNode = NULL;
132 // Switch off camera.
133 dc1394_camera_off( m_handle, m_node );
134 // Free handle.
135 dc1394_destroy_handle( m_handle ); m_handle = NULL;
136 };
137 }
138  
139 template< typename T >
140 dc1394_feature_info image_dc1394input< T >::get_feature( int _id )
141 throw (mimasexception)
142 {
143 dc1394_feature_info retval; retval.feature_id = _id;
144 MMERROR( dc1394_get_camera_feature( m_handle, m_node, &retval ) != 0,
145 mimasexception, ,
146 "Error requesting feature " << _id << " from firewire "
147 "digital camera." );
148 return retval;
149 }
150  
151 template< typename T >
152 unsigned int image_dc1394input< T >::get_feature_value( int id )
153 throw (mimasexception)
154 {
155 MMERROR( m_handle != NULL, mimasexception, ,
156 "Camera device was closed already." );
157 unsigned int retval;
158 MMERROR( dc1394_get_feature_value( m_handle, m_node, id, &retval ) != 0,
159 mimasexception, ,
160 "Error requesting value of feature " << id
161 << " from firewire digital camera." );
162 return retval;
163 }
164  
165 template< typename T >
166 void image_dc1394input< T >::set_feature_value( int id,
167 unsigned int value )
168 throw (mimasexception)
169 {
170 MMERROR( m_handle != NULL, mimasexception, ,
171 "Camera device was closed already." );
172 MMERROR( dc1394_set_feature_value( m_handle, m_node, id, value ) != 0,
173 mimasexception, ,
174 "Error setting feature " << id << " from firewire "
175 "digital camera." );
176 }
177  
178 template< typename T >
179 void image_dc1394input< T >::selectFormat( int preferredFormat ) throw (mimasexception)
180 {
181 typedef struct {
182 int format;
183 const char *name;
184 } FormatEntry;
185 FormatEntry format[] = {
186 { FORMAT_SCALABLE_IMAGE_SIZE , "FORMAT_SCALABLE_IMAGE_SIZE" },
187 { FORMAT_SVGA_NONCOMPRESSED_2, "FORMAT_SVGA_NONCOMPRESSED_2" },
188 { FORMAT_SVGA_NONCOMPRESSED_1, "FORMAT_SVGA_NONCOMPRESSED_1" },
189 { FORMAT_VGA_NONCOMPRESSED , "FORMAT_VGA_NONCOMPRESSED" },
190 { FORMAT_STILL_IMAGE , "FORMAT_STILL_IMAGE" }
191 };
192 const char *namePreferred = "invalid format number";
193  
194 // Get list of supported formats.
195 quadlet_t formats = 0;
196 MMERROR( dc1394_query_supported_formats
197 ( m_handle, m_cameraNode[ m_node ], &formats )
198 == DC1394_SUCCESS, mimasexception, ,
199 "Error requesting supported video formats." );
200  
201 int selected = 0;
202 std::ostringstream s;
203  
204 while ( true ) {
205  
206 if ( format[ selected ].format == preferredFormat )
207 namePreferred = format[ selected ].name;
208  
209 // Check wether format is supported.
210 if ( ( formats & ( 1U << ( 31 + FORMAT_MIN -
211 format[ selected ].format ) ) ) != 0 ) {
212 if ( preferredFormat == format[ selected ].format ||
213 preferredFormat == -1 ) {
214 m_format = format[ selected ].format;
215 break;
216 };
217 s << " " << format[ selected ].name;
218 };
219 selected++;
220 if ( selected >= (signed)(sizeof(format)/sizeof(FormatEntry)) ) {
221 MMERROR( preferredFormat == -1, mimasexception, ,
222 "Preferred format \"" << namePreferred
223 << "\" not supported by camera (supported:"
224 << s.str() << ")." );
225 MMERROR( false, mimasexception, ,
226 "Camera-driver doesn't offer a known video-format." );
227 };
228  
229 };
230 assert( m_format != -1 );
231 }
232  
233 template< typename T >
234 void image_dc1394input< T >::selectMode( int preferredMode ) throw (mimasexception)
235 {
236 typedef struct {
237 ColourSpace colourSpace;
238 int mode;
239 const char *name;
240 } ModeEntry;
241 ModeEntry mode[] = {
242 { UYVY , MODE_640x480_YUV422 , "MODE_640x480_YUV422" },
243 { UYVY , MODE_320x240_YUV422 , "MODE_320x200_YUV422" },
244 { Grey8 , MODE_640x480_MONO , "MODE_640x480_MONO" },
245 { RGB24 , MODE_640x480_RGB , "MODE_640x480_RGB" },
246 { Unknown, MODE_640x480_YUV411 , "MODE_640x480_YUV411" },
247 { Unknown, MODE_640x480_MONO16 , "MODE_640x480_MONO16" },
248 { Unknown, MODE_160x120_YUV444 , "MODE_160x120_YUV444" },
249  
250 { UYVY , MODE_1024x768_YUV422 , "MODE_1024x768_YUV422" },
251 { Grey8 , MODE_1024x768_MONO , "MODE_1024x768_MONO" },
252 { RGB24 , MODE_1024x768_RGB , "MODE_1024x768_RGB" },
253 { UYVY , MODE_800x600_YUV422 , "MODE_800x600_YUV422" },
254 { Grey8 , MODE_800x600_MONO , "MODE_800x600_MONO" },
255 { RGB24 , MODE_800x600_RGB , "MODE_800x600_RGB" },
256 { Unknown, MODE_1024x768_MONO16 , "MODE_1024x768_MONO16" },
257 { Unknown, MODE_800x600_MONO16 , "MODE_800x600_MONO16" },
258  
259 { UYVY , MODE_1600x1200_YUV422, "MODE_1600x1200_YUV422" },
260 { Grey8 , MODE_1600x1200_MONO , "MODE_1600x1200_MONO" },
261 { RGB24 , MODE_1600x1200_RGB , "MODE_1600x1200_RGB" },
262 { UYVY , MODE_1280x960_YUV422 , "MODE_1280x960_YUV422" },
263 { Grey8 , MODE_1280x960_MONO , "MODE_1280x960_MONO" },
264 { RGB24 , MODE_1280x960_RGB , "MODE_1280x960_RGB" },
265 { Unknown, MODE_1600x1200_MONO16, "MODE_1600x1200_MONO16" },
266 { Unknown, MODE_1280x960_MONO16 , "MODE_1280x960_MONO16" },
267  
268 { Unknown, MODE_EXIF , "MODE_EXIF" },
269  
270 { Unknown, MODE_FORMAT7_7 , "MODE_FORMAT7_7" },
271 { Unknown, MODE_FORMAT7_6 , "MODE_FORMAT7_6" },
272 { Unknown, MODE_FORMAT7_5 , "MODE_FORMAT7_5" },
273 { Unknown, MODE_FORMAT7_4 , "MODE_FORMAT7_4" },
274 { Unknown, MODE_FORMAT7_3 , "MODE_FORMAT7_3" },
275 { Unknown, MODE_FORMAT7_2 , "MODE_FORMAT7_2" },
276 { Unknown, MODE_FORMAT7_1 , "MODE_FORMAT7_1" },
277 { Unknown, MODE_FORMAT7_0 , "MODE_FORMAT7_0" }
278 };
279 const char *namePreferred = "invalid mode number";
280  
281 // Get list of supported video modes.
282 quadlet_t videoModes = 0;
283 MMERROR( dc1394_query_supported_modes
284 ( m_handle, m_cameraNode[ m_node ], m_format,
285 &videoModes )
286 == DC1394_SUCCESS, mimasexception, ,
287 "Error requesting supported video modes." );
288 int
289 modesMin = 0,
290 modesMax = -1;
291 switch ( m_format ) {
292 case FORMAT_VGA_NONCOMPRESSED:
293 modesMin = MODE_FORMAT0_MIN;
294 modesMax = MODE_FORMAT0_MAX;
295 break;
296 case FORMAT_SVGA_NONCOMPRESSED_1:
297 modesMin = MODE_FORMAT1_MIN;
298 modesMax = MODE_FORMAT1_MAX;
299 break;
300 case FORMAT_SVGA_NONCOMPRESSED_2:
301 modesMin = MODE_FORMAT2_MIN;
302 modesMax = MODE_FORMAT2_MAX;
303 break;
304 case FORMAT_STILL_IMAGE:
305 modesMin = MODE_FORMAT6_MIN;
306 modesMax = MODE_FORMAT6_MAX;
307 break;
308 case FORMAT_SCALABLE_IMAGE_SIZE:
309 modesMin = MODE_FORMAT7_MIN;
310 modesMax = MODE_FORMAT7_MAX;
311 break;
312 default:
313 assert( false );
314 };
315  
316 int selected = 0;
317 std::ostringstream s;
318  
319 while ( true ) {
320  
321 if ( mode[ selected ].mode == preferredMode )
322 namePreferred = mode[ selected ].name;
323  
324 if ( mode[ selected ].mode >= modesMin &&
325 mode[ selected ].mode <= modesMax ) {
326 if ( ( videoModes & ( 1U << ( 31 + modesMin -
327 mode[ selected ].mode ) ) ) != 0 ) {
328 if ( preferredMode == mode[ selected ].mode ||
329 preferredMode == -1 ) {
330 m_mode = mode[ selected ].mode;
331 m_colourSpace = mode[ selected ].colourSpace;
332 break;
333 };
334 s << " " << mode[ selected ].name;
335 };
336 };
337  
338 selected++;
339 if ( selected >= (signed)(sizeof(mode)/sizeof(ModeEntry)) ) {
340 MMERROR( preferredMode == -1 ||
341 ( preferredMode >= modesMin &&
342 preferredMode <= modesMax ),
343 mimasexception, ,
344 "Mode \"" << namePreferred << "\" not allowed with "
345 "current format (allowed and supported:"
346 << s.str() << ")." );
347 MMERROR( preferredMode == -1, mimasexception, ,
348 "Preferred mode \"" << namePreferred
349 << "\" not supported in this format (supported:"
350 << s.str() << ")." );
351 MMERROR( false, mimasexception, ,
352 "The current video format doesn't offer a known mode." );
353 };
354  
355 };
356 assert( m_mode != -1 );
357 MMERROR( m_colourSpace != Unknown ||
358 m_format == FORMAT_SCALABLE_IMAGE_SIZE,
359 mimasexception, , "Colourspace transformation for "
360 << mode[ selected ].name
361 << "-images not implemented." );
362 }
363  
364 template< typename T >
365 void image_dc1394input< T >::selectFrameRate( int preferredFrameRate ) throw (mimasexception)
366 {
367 typedef struct {
368 int rate;
369 const char *name;
370 } RateEntry;
371 RateEntry rate[] = {
372 { FRAMERATE_240 , "FRAMERATE_240" },
373 { FRAMERATE_120 , "FRAMERATE_120" },
374 { FRAMERATE_60 , "FRAMERATE_60" },
375 { FRAMERATE_30 , "FRAMERATE_30" },
376 { FRAMERATE_15 , "FRAMERATE_15" },
377 { FRAMERATE_7_5 , "FRAMERATE_7_5" },
378 { FRAMERATE_3_75 , "FRAMERATE_3_75" },
379 { FRAMERATE_1_875, "FRAMERATE_1_875" }
380 };
381 const char *namePreferred = "invalid frame rate index";
382 // Get list of possible framerates.
383 quadlet_t frameRates = 0;
384 MMERROR( dc1394_query_supported_framerates
385 ( m_handle, m_cameraNode[ m_node ], m_format,
386 m_mode, &frameRates )
387 == DC1394_SUCCESS, mimasexception, ,
388 "Error requesting supported framerates." );
389  
390 int selected = 0;
391 std::ostringstream s;
392  
393 while ( true ) {
394  
395 if ( rate[ selected ].rate == preferredFrameRate )
396 namePreferred = rate[ selected ].name;
397  
398 // Check wether frameRate is supported.
399 if ( ( frameRates & ( 1U << ( 31 + FRAMERATE_MIN -
400 rate[ selected ].rate ) ) ) != 0 ) {
401 if ( preferredFrameRate == rate[ selected ].rate ||
402 preferredFrameRate == -1 ) {
403 m_frameRate = rate[ selected ].rate;
404 break;
405 };
406 s << " " << rate[ selected ].name;
407 };
408 selected++;
409 if ( selected >= (signed)(sizeof(rate)/sizeof(RateEntry)) ) {
410 MMERROR( preferredFrameRate == -1, mimasexception, ,
411 "Preferred frameRate \"" << namePreferred
412 << "\" not supported in this mode (supported:"
413 << s.str() << ")." );
414 MMERROR( false, mimasexception, ,
415 "Camera-driver doesn't offer a known frame-rate." );
416 };
417  
418 };
419 assert( m_frameRate != -1 );
420  
421 }
422  
423 template< typename T >
424 void image_dc1394input< T >::selectFormat7Colour( int preferredFormat7Colour )
425 throw (mimasexception)
426 {
427 assert( m_format == FORMAT_SCALABLE_IMAGE_SIZE );
428 typedef struct {
429 ColourSpace colourSpace;
430 int colour;
431 const char *name;
432 } ColourEntry;
433 ColourEntry colour[] = {
434 { UYVY , COLOR_FORMAT7_YUV422 , "COLOR_FORMAT7_YUV422" },
435 { Grey8 , COLOR_FORMAT7_MONO8 , "COLOR_FORMAT7_MONO8" },
436 { RGB24 , COLOR_FORMAT7_RGB8 , "COLOR_FORMAT7_RGB8" },
437 { Unknown, COLOR_FORMAT7_YUV411 , "COLOR_FORMAT7_YUV411" },
438 { Unknown, COLOR_FORMAT7_YUV444 , "COLOR_FORMAT7_YUV444" },
439 { Unknown, COLOR_FORMAT7_MONO16 , "COLOR_FORMAT7_MONO16" },
440 { Unknown, COLOR_FORMAT7_RGB16 , "COLOR_FORMAT7_RGB16" },
441 { Unknown, COLOR_FORMAT7_MONO16S, "COLOR_FORMAT7_MONO16S" },
442 { Unknown, COLOR_FORMAT7_RGB16S , "COLOR_FORMAT7_RGB16S" },
443 { Unknown, COLOR_FORMAT7_RAW8 , "COLOR_FORMAT7_RAW8" },
444 { Unknown, COLOR_FORMAT7_RAW16 , "COLOR_FORMAT7_RAW16" }
445 };
446 const char *namePreferred = "invalid format7 color index";
447 // Get list of possible format7 colours.
448 quadlet_t colours = 0;
449 MMERROR( dc1394_query_format7_color_coding
450 ( m_handle, m_cameraNode[ m_node ],
451 m_mode, &colours ) == DC1394_SUCCESS, mimasexception, ,
452 "Error requesting format7 colourspaces." );
453  
454 int selected = 0;
455 std::ostringstream s;
456  
457 while ( true ) {
458  
459 if ( colour[ selected ].colour == preferredFormat7Colour )
460 namePreferred = colour[ selected ].name;
461  
462 // Check wether colour is supported.
463 if ( ( colours & ( 1U << ( 31 + COLOR_FORMAT7_MIN -
464 colour[ selected ].colour ) ) ) != 0 ) {
465 if ( preferredFormat7Colour == colour[ selected ].colour ||
466 preferredFormat7Colour == -1 ) {
467 m_format7Colour = colour[ selected ].colour;
468 m_colourSpace = colour[ selected ].colourSpace;
469 break;
470 };
471 s << " " << colour[ selected ].name;
472 };
473 selected++;
474 if ( selected >= (signed)(sizeof(colour)/sizeof(ColourEntry)) ) {
475 MMERROR( preferredFormat7Colour == -1, mimasexception, ,
476 "Preferred format7 colour \"" << namePreferred
477 << "\" not supported in this mode (supported:"
478 << s.str() << ")." );
479 MMERROR( false, mimasexception, ,
480 "Camera-driver doesn't offer a known format7 colour in "
481 "this mode." );
482 };
483  
484 }
485 assert( m_format7Colour != -1 );
486 MMERROR( m_colourSpace != Unknown,
487 mimasexception, , "Colourspace transformation for "
488 << colour[ selected ].name << "-images not implemented." );
489 }
490  
491 };