hornetseye-v4l2 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -7,15 +7,15 @@ require 'rake/loaders/makefile'
7
7
  require 'rbconfig'
8
8
 
9
9
  PKG_NAME = 'hornetseye-v4l2'
10
- PKG_VERSION = '0.1.0'
10
+ PKG_VERSION = '0.2.0'
11
+ CFG = RbConfig::CONFIG
11
12
  CXX = ENV[ 'CXX' ] || 'g++'
12
- STRIP = ENV[ 'STRIP' ] || 'strip'
13
13
  RB_FILES = FileList[ 'lib/**/*.rb' ]
14
14
  CC_FILES = FileList[ 'ext/*.cc' ]
15
15
  HH_FILES = FileList[ 'ext/*.hh' ] + FileList[ 'ext/*.tcc' ]
16
16
  TC_FILES = FileList[ 'test/tc_*.rb' ]
17
17
  TS_FILES = FileList[ 'test/ts_*.rb' ]
18
- SO_FILE = "ext/#{PKG_NAME.tr '\-', '_'}.so"
18
+ SO_FILE = "ext/#{PKG_NAME.tr '\-', '_'}.#{CFG[ 'DLEXT' ]}"
19
19
  PKG_FILES = [ 'Rakefile', 'README.md', 'COPYING', '.document' ] +
20
20
  RB_FILES + CC_FILES + HH_FILES + TS_FILES + TC_FILES
21
21
  BIN_FILES = [ 'README.md', 'COPYING', '.document', SO_FILE ] +
@@ -27,17 +27,18 @@ EMAIL = %q{jan@wedesoft.de}
27
27
  HOMEPAGE = %q{http://wedesoft.github.com/hornetseye-v4l2/}
28
28
 
29
29
  OBJ = CC_FILES.ext 'o'
30
- $CXXFLAGS = ENV[ 'CXXFLAGS' ] || ''
31
- $CXXFLAGS = "#{$CXXFLAGS} -fPIC -DNDEBUG"
32
- if RbConfig::CONFIG[ 'rubyhdrdir' ]
33
- $CXXFLAGS = "#{$CXXFLAGS} -I#{RbConfig::CONFIG[ 'rubyhdrdir' ]} " +
34
- "-I#{RbConfig::CONFIG[ 'rubyhdrdir' ]}/#{RbConfig::CONFIG[ 'arch' ]}"
30
+ $CXXFLAGS = "-DNDEBUG #{CFG[ 'CPPFLAGS' ]} #{CFG[ 'CFLAGS' ]}"
31
+ if CFG[ 'rubyhdrdir' ]
32
+ $CXXFLAGS = "#{$CXXFLAGS} -I#{CFG[ 'rubyhdrdir' ]} " +
33
+ "-I#{CFG[ 'rubyhdrdir' ]}/#{CFG[ 'arch' ]}"
35
34
  else
36
- $CXXFLAGS = "#{$CXXFLAGS} -I#{RbConfig::CONFIG[ 'archdir' ]}"
35
+ $CXXFLAGS = "#{$CXXFLAGS} -I#{CFG[ 'archdir' ]}"
37
36
  end
38
- $LIBRUBYARG = RbConfig::CONFIG[ 'LIBRUBYARG' ]
39
- $SITELIBDIR = RbConfig::CONFIG[ 'sitelibdir' ]
40
- $SITEARCHDIR = RbConfig::CONFIG[ 'sitearchdir' ]
37
+ $LIBRUBYARG = "-L#{CFG[ 'libdir' ]} #{CFG[ 'LIBRUBYARG' ]} #{CFG[ 'LDFLAGS' ]} " +
38
+ "#{CFG[ 'SOLIBS' ]} #{CFG[ 'DLDLIBS' ]}"
39
+ $SITELIBDIR = CFG[ 'sitelibdir' ]
40
+ $SITEARCHDIR = CFG[ 'sitearchdir' ]
41
+ $LDSHARED = CFG[ 'LDSHARED' ][ CFG[ 'LDSHARED' ].index( ' ' ) .. -1 ]
41
42
 
42
43
  task :default => :all
43
44
 
@@ -46,7 +47,6 @@ task :all => [ SO_FILE ]
46
47
 
47
48
  file SO_FILE => OBJ do |t|
48
49
  sh "#{CXX} -shared -o #{t.name} #{OBJ} -lv4l2 #{$LIBRUBYARG}"
49
- # sh "#{STRIP} --strip-all #{t.name}"
50
50
  end
51
51
 
52
52
  task :test => [ SO_FILE ]
@@ -171,7 +171,7 @@ rule '.o' => '.cc' do |t|
171
171
  end
172
172
 
173
173
  file ".depends.mf" do |t|
174
- sh "g++ -MM #{$CXXFLAGS} #{CC_FILES.join ' '} | " +
174
+ sh "g++ -MM #{CC_FILES.join ' '} | " +
175
175
  "sed -e :a -e N -e 's/\\n/\\$/g' -e ta | " +
176
176
  "sed -e 's/ *\\\\\\$ */ /g' -e 's/\\$/\\n/g' | sed -e 's/^/ext\\//' > #{t.name}"
177
177
  end
data/ext/frame.cc CHANGED
@@ -60,6 +60,11 @@ char *Frame::data(void)
60
60
  return ptr;
61
61
  }
62
62
 
63
+ bool Frame::rgb(void)
64
+ {
65
+ return rb_funcall( m_frame, rb_intern( "rgb?" ), 0 ) != Qfalse;
66
+ }
67
+
63
68
  void Frame::markRubyMember(void)
64
69
  {
65
70
  rb_gc_mark( m_frame );
data/ext/frame.hh CHANGED
@@ -30,6 +30,7 @@ public:
30
30
  int width(void);
31
31
  int height(void);
32
32
  char *data(void);
33
+ bool rgb(void);
33
34
  VALUE rubyObject(void) { return m_frame; }
34
35
  void markRubyMember(void);
35
36
  static int storageSize( const std::string &typecode, int width, int height );
data/ext/v4l2input.cc CHANGED
@@ -30,9 +30,7 @@ using namespace std;
30
30
 
31
31
  VALUE V4L2Input::cRubyClass = Qnil;
32
32
 
33
- V4L2Input::V4L2Input( const string &device, int width, int height,
34
- string preferredTypecode )
35
- throw (Error):
33
+ V4L2Input::V4L2Input( const std::string &device, V4L2SelectPtr select ) throw (Error):
36
34
  m_device(device), m_fd(-1), m_io(IO_READ), m_frameUsed(false)
37
35
  {
38
36
  m_map[ 0 ] = MAP_FAILED;
@@ -59,7 +57,78 @@ V4L2Input::V4L2Input( const string &device, int width, int height,
59
57
  #endif
60
58
  ERRORMACRO( capability.capabilities & V4L2_CAP_VIDEO_CAPTURE != 0,
61
59
  Error, , m_device << " is no video capture device" );
62
- selectPalette( width, height, preferredTypecode );
60
+ unsigned int formatIndex = 0;
61
+ while ( true ) {
62
+ struct v4l2_fmtdesc format;
63
+ memset( &format, 0, sizeof(format) );
64
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
65
+ format.index = formatIndex++;
66
+ int r = xioctl( VIDIOC_ENUM_FMT, &format );
67
+ if ( r != 0 ) break;
68
+ unsigned int frameSizeIndex = 0;
69
+ while ( true ) {
70
+ struct v4l2_frmsizeenum pix;
71
+ memset( &pix, 0, sizeof(pix) );
72
+ pix.pixel_format = format.pixelformat;
73
+ pix.index = frameSizeIndex++;
74
+ int r = xioctl( VIDIOC_ENUM_FRAMESIZES, &pix );
75
+ if ( r != 0 ) break;
76
+ if ( pix.type == V4L2_FRMSIZE_TYPE_DISCRETE )
77
+ select->add( format.pixelformat, pix.discrete.width, pix.discrete.height );
78
+ else if ( pix.type == V4L2_FRMSIZE_TYPE_STEPWISE ) {
79
+ unsigned int
80
+ w = pix.stepwise.min_width,
81
+ h = pix.stepwise.min_height;
82
+ while ( w <= pix.stepwise.max_width && h <= pix.stepwise.max_height ) {
83
+ select->add( format.pixelformat, w, h );
84
+ w += pix.stepwise.step_width;
85
+ h += pix.stepwise.step_height;
86
+ };
87
+ } else {
88
+ select->add( format.pixelformat,
89
+ pix.stepwise.max_width, pix.stepwise.max_height );
90
+ };
91
+ };
92
+ };
93
+ unsigned int selection = select->make();
94
+ unsigned int coding = select->coding( selection );
95
+ #ifndef NDEBUG
96
+ cerr << "selection = " << selection << endl
97
+ << "coding = " << select->coding( selection ) << endl
98
+ << "w = " << select->width( selection ) << endl
99
+ << "h = " << select->height( selection ) << endl;
100
+ #endif
101
+ m_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
102
+ m_format.fmt.pix.field = V4L2_FIELD_NONE;
103
+ m_format.fmt.pix.width = select->width( selection );
104
+ m_format.fmt.pix.height = select->height( selection );
105
+ m_format.fmt.pix.pixelformat = coding;
106
+ m_format.fmt.pix.field = V4L2_FIELD_SEQ_TB;
107
+ ERRORMACRO( xioctl( VIDIOC_S_FMT, &m_format ) == 0, Error, ,
108
+ "Error switching device \"" << m_device << "\" to selected format" );
109
+ switch ( coding ) {
110
+ case V4L2_PIX_FMT_UYVY:
111
+ m_typecode = "UYVY";
112
+ break;
113
+ case V4L2_PIX_FMT_YUYV:
114
+ m_typecode = "YUY2";
115
+ break;
116
+ case V4L2_PIX_FMT_YUV420:
117
+ m_typecode = "I420";
118
+ break;
119
+ case V4L2_PIX_FMT_GREY:
120
+ m_typecode = "UBYTE";
121
+ break;
122
+ case V4L2_PIX_FMT_RGB24:
123
+ m_typecode = "UBYTERGB";
124
+ break;
125
+ case V4L2_PIX_FMT_MJPEG:
126
+ m_typecode = "MJPG";
127
+ break;
128
+ default:
129
+ ERRORMACRO( false, Error, , "Conversion for DC1394 colorspace " << coding
130
+ << " not implemented yet" );
131
+ };
63
132
  if ( capability.capabilities & V4L2_CAP_STREAMING ) {
64
133
  try {
65
134
  #ifndef NDEBUG
@@ -386,78 +455,195 @@ FramePtr V4L2Input::read(void) throw (Error)
386
455
  VALUE V4L2Input::registerRubyClass( VALUE module )
387
456
  {
388
457
  cRubyClass = rb_define_class_under( module, "V4L2Input", rb_cObject );
389
- rb_define_const( cRubyClass, "V4L2_CTRL_TYPE_INTEGER",
390
- INT2FIX(V4L2_CTRL_TYPE_INTEGER) );
391
- rb_define_const( cRubyClass, "V4L2_CTRL_TYPE_BOOLEAN",
392
- INT2FIX(V4L2_CTRL_TYPE_BOOLEAN) );
393
- rb_define_const( cRubyClass, "V4L2_CTRL_TYPE_MENU",
394
- INT2FIX(V4L2_CTRL_TYPE_MENU) );
395
- rb_define_const( cRubyClass, "V4L2_CTRL_TYPE_BUTTON",
396
- INT2FIX(V4L2_CTRL_TYPE_BUTTON) );
397
- // #ifdef V4L2_CTRL_TYPE_CTRL_CLASS
398
- rb_define_const( cRubyClass, "V4L2_CTRL_TYPE_CTRL_CLASS",
399
- INT2FIX(V4L2_CTRL_TYPE_CTRL_CLASS) );
400
- // #endif
401
- rb_define_const( cRubyClass, "V4L2_CID_BASE",
402
- INT2FIX(V4L2_CID_BASE) );
403
- // #ifdef V4L2_CID_USER_BASE
404
- rb_define_const( cRubyClass, "V4L2_CID_USER_BASE",
405
- INT2FIX(V4L2_CID_USER_BASE) );
406
- // #endif
407
- rb_define_const( cRubyClass, "V4L2_CID_PRIVATE_BASE",
408
- INT2FIX(V4L2_CID_PRIVATE_BASE) );
409
- rb_define_const( cRubyClass, "V4L2_CID_BRIGHTNESS",
410
- INT2FIX(V4L2_CID_BRIGHTNESS) );
411
- rb_define_const( cRubyClass, "V4L2_CID_CONTRAST",
412
- INT2FIX(V4L2_CID_CONTRAST) );
413
- rb_define_const( cRubyClass, "V4L2_CID_SATURATION",
414
- INT2FIX(V4L2_CID_SATURATION) );
415
- rb_define_const( cRubyClass, "V4L2_CID_HUE",
416
- INT2FIX(V4L2_CID_HUE) );
417
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_VOLUME",
418
- INT2FIX(V4L2_CID_AUDIO_VOLUME) );
419
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_BALANCE",
420
- INT2FIX(V4L2_CID_AUDIO_BALANCE) );
421
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_BASS",
422
- INT2FIX(V4L2_CID_AUDIO_BASS) );
423
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_TREBLE",
424
- INT2FIX(V4L2_CID_AUDIO_TREBLE) );
425
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_MUTE",
426
- INT2FIX(V4L2_CID_AUDIO_MUTE) );
427
- rb_define_const( cRubyClass, "V4L2_CID_AUDIO_LOUDNESS",
428
- INT2FIX(V4L2_CID_AUDIO_LOUDNESS) );
429
- rb_define_const( cRubyClass, "V4L2_CID_BLACK_LEVEL",
430
- INT2FIX(V4L2_CID_BLACK_LEVEL) );
431
- rb_define_const( cRubyClass, "V4L2_CID_AUTO_WHITE_BALANCE",
432
- INT2FIX(V4L2_CID_AUTO_WHITE_BALANCE) );
433
- rb_define_const( cRubyClass, "V4L2_CID_DO_WHITE_BALANCE",
434
- INT2FIX(V4L2_CID_DO_WHITE_BALANCE) );
435
- rb_define_const( cRubyClass, "V4L2_CID_RED_BALANCE",
436
- INT2FIX(V4L2_CID_RED_BALANCE) );
437
- rb_define_const( cRubyClass, "V4L2_CID_BLUE_BALANCE",
438
- INT2FIX(V4L2_CID_BLUE_BALANCE) );
439
- rb_define_const( cRubyClass, "V4L2_CID_GAMMA",
440
- INT2FIX(V4L2_CID_GAMMA) );
441
- rb_define_const( cRubyClass, "V4L2_CID_WHITENESS",
442
- INT2FIX(V4L2_CID_WHITENESS) );
443
- rb_define_const( cRubyClass, "V4L2_CID_EXPOSURE",
444
- INT2FIX(V4L2_CID_EXPOSURE) );
445
- rb_define_const( cRubyClass, "V4L2_CID_AUTOGAIN",
446
- INT2FIX(V4L2_CID_AUTOGAIN) );
447
- rb_define_const( cRubyClass, "V4L2_CID_GAIN",
448
- INT2FIX(V4L2_CID_GAIN) );
449
- rb_define_const( cRubyClass, "V4L2_CID_HFLIP",
450
- INT2FIX(V4L2_CID_HFLIP) );
451
- rb_define_const( cRubyClass, "V4L2_CID_VFLIP",
452
- INT2FIX(V4L2_CID_VFLIP) );
453
- rb_define_const( cRubyClass, "V4L2_CID_HCENTER",
454
- INT2FIX(V4L2_CID_HCENTER) );
455
- rb_define_const( cRubyClass, "V4L2_CID_VCENTER",
456
- INT2FIX(V4L2_CID_VCENTER) );
457
- rb_define_const( cRubyClass, "V4L2_CID_LASTP1",
458
- INT2FIX(V4L2_CID_LASTP1) );
459
- rb_define_singleton_method( cRubyClass, "new",
460
- RUBY_METHOD_FUNC( wrapNew ), 4 );
458
+ rb_define_const( cRubyClass, "MODE_RGB332",
459
+ INT2NUM(V4L2_PIX_FMT_RGB332) );
460
+ rb_define_const( cRubyClass, "MODE_RGB444",
461
+ INT2NUM(V4L2_PIX_FMT_RGB444) );
462
+ rb_define_const( cRubyClass, "MODE_RGB555",
463
+ INT2NUM(V4L2_PIX_FMT_RGB555) );
464
+ rb_define_const( cRubyClass, "MODE_RGB565",
465
+ INT2NUM(V4L2_PIX_FMT_RGB565) );
466
+ rb_define_const( cRubyClass, "MODE_RGB555X",
467
+ INT2NUM(V4L2_PIX_FMT_RGB555X) );
468
+ rb_define_const( cRubyClass, "MODE_RGB565X",
469
+ INT2NUM(V4L2_PIX_FMT_RGB565X) );
470
+ rb_define_const( cRubyClass, "MODE_BGR24",
471
+ INT2NUM(V4L2_PIX_FMT_BGR24) );
472
+ rb_define_const( cRubyClass, "MODE_RGB24",
473
+ INT2NUM(V4L2_PIX_FMT_RGB24) );
474
+ rb_define_const( cRubyClass, "MODE_BGR32",
475
+ INT2NUM(V4L2_PIX_FMT_BGR32) );
476
+ rb_define_const( cRubyClass, "MODE_RGB32",
477
+ INT2NUM(V4L2_PIX_FMT_RGB32) );
478
+ rb_define_const( cRubyClass, "MODE_GREY",
479
+ INT2NUM(V4L2_PIX_FMT_GREY) );
480
+ rb_define_const( cRubyClass, "MODE_Y16",
481
+ INT2NUM(V4L2_PIX_FMT_Y16) );
482
+ rb_define_const( cRubyClass, "MODE_PAL8",
483
+ INT2NUM(V4L2_PIX_FMT_PAL8) );
484
+ rb_define_const( cRubyClass, "MODE_YVU410",
485
+ INT2NUM(V4L2_PIX_FMT_YVU410) );
486
+ rb_define_const( cRubyClass, "MODE_YVU420",
487
+ INT2NUM(V4L2_PIX_FMT_YVU420) );
488
+ rb_define_const( cRubyClass, "MODE_YUYV",
489
+ INT2NUM(V4L2_PIX_FMT_YUYV) );
490
+ rb_define_const( cRubyClass, "MODE_YYUV",
491
+ INT2NUM(V4L2_PIX_FMT_YYUV) );
492
+ rb_define_const( cRubyClass, "MODE_YVYU",
493
+ INT2NUM(V4L2_PIX_FMT_YVYU) );
494
+ rb_define_const( cRubyClass, "MODE_UYVY",
495
+ INT2NUM(V4L2_PIX_FMT_UYVY) );
496
+ rb_define_const( cRubyClass, "MODE_VYUY",
497
+ INT2NUM(V4L2_PIX_FMT_VYUY) );
498
+ rb_define_const( cRubyClass, "MODE_YUV422P",
499
+ INT2NUM(V4L2_PIX_FMT_YUV422P) );
500
+ rb_define_const( cRubyClass, "MODE_YUV411P",
501
+ INT2NUM(V4L2_PIX_FMT_YUV411P) );
502
+ rb_define_const( cRubyClass, "MODE_Y41P",
503
+ INT2NUM(V4L2_PIX_FMT_Y41P) );
504
+ rb_define_const( cRubyClass, "MODE_YUV444",
505
+ INT2NUM(V4L2_PIX_FMT_YUV444) );
506
+ rb_define_const( cRubyClass, "MODE_YUV555",
507
+ INT2NUM(V4L2_PIX_FMT_YUV555) );
508
+ rb_define_const( cRubyClass, "MODE_YUV565",
509
+ INT2NUM(V4L2_PIX_FMT_YUV565) );
510
+ rb_define_const( cRubyClass, "MODE_YUV32",
511
+ INT2NUM(V4L2_PIX_FMT_YUV32) );
512
+ rb_define_const( cRubyClass, "MODE_YUV410",
513
+ INT2NUM(V4L2_PIX_FMT_YUV410) );
514
+ rb_define_const( cRubyClass, "MODE_YUV420",
515
+ INT2NUM(V4L2_PIX_FMT_YUV420) );
516
+ rb_define_const( cRubyClass, "MODE_HI240",
517
+ INT2NUM(V4L2_PIX_FMT_HI240) );
518
+ rb_define_const( cRubyClass, "MODE_HM12",
519
+ INT2NUM(V4L2_PIX_FMT_HM12) );
520
+ rb_define_const( cRubyClass, "MODE_NV12",
521
+ INT2NUM(V4L2_PIX_FMT_NV12) );
522
+ rb_define_const( cRubyClass, "MODE_NV21",
523
+ INT2NUM(V4L2_PIX_FMT_NV21) );
524
+ rb_define_const( cRubyClass, "MODE_NV16",
525
+ INT2NUM(V4L2_PIX_FMT_NV16) );
526
+ rb_define_const( cRubyClass, "MODE_NV61",
527
+ INT2NUM(V4L2_PIX_FMT_NV61) );
528
+ rb_define_const( cRubyClass, "MODE_SBGGR8",
529
+ INT2NUM(V4L2_PIX_FMT_SBGGR8) );
530
+ rb_define_const( cRubyClass, "MODE_SGBRG8",
531
+ INT2NUM(V4L2_PIX_FMT_SGBRG8) );
532
+ rb_define_const( cRubyClass, "MODE_SGRBG8",
533
+ INT2NUM(V4L2_PIX_FMT_SGRBG8) );
534
+ rb_define_const( cRubyClass, "MODE_SGRBG10",
535
+ INT2NUM(V4L2_PIX_FMT_SGRBG10) );
536
+ rb_define_const( cRubyClass, "MODE_SGRBG10DPCM8",
537
+ INT2NUM(V4L2_PIX_FMT_SGRBG10DPCM8) );
538
+ rb_define_const( cRubyClass, "MODE_SBGGR16",
539
+ INT2NUM(V4L2_PIX_FMT_SBGGR16) );
540
+ rb_define_const( cRubyClass, "MODE_MJPEG",
541
+ INT2NUM(V4L2_PIX_FMT_MJPEG) );
542
+ rb_define_const( cRubyClass, "MODE_JPEG",
543
+ INT2NUM(V4L2_PIX_FMT_JPEG) );
544
+ rb_define_const( cRubyClass, "MODE_DV",
545
+ INT2NUM(V4L2_PIX_FMT_DV) );
546
+ rb_define_const( cRubyClass, "MODE_MPEG",
547
+ INT2NUM(V4L2_PIX_FMT_MPEG) );
548
+ rb_define_const( cRubyClass, "MODE_WNVA",
549
+ INT2NUM(V4L2_PIX_FMT_WNVA) );
550
+ rb_define_const( cRubyClass, "MODE_SN9C10X",
551
+ INT2NUM(V4L2_PIX_FMT_SN9C10X) );
552
+ rb_define_const( cRubyClass, "MODE_SN9C20X_I420",
553
+ INT2NUM(V4L2_PIX_FMT_SN9C20X_I420) );
554
+ rb_define_const( cRubyClass, "MODE_PWC1",
555
+ INT2NUM(V4L2_PIX_FMT_PWC1) );
556
+ rb_define_const( cRubyClass, "MODE_PWC2",
557
+ INT2NUM(V4L2_PIX_FMT_PWC2) );
558
+ rb_define_const( cRubyClass, "MODE_ET61X251",
559
+ INT2NUM(V4L2_PIX_FMT_ET61X251) );
560
+ rb_define_const( cRubyClass, "MODE_SPCA501",
561
+ INT2NUM(V4L2_PIX_FMT_SPCA501) );
562
+ rb_define_const( cRubyClass, "MODE_SPCA505",
563
+ INT2NUM(V4L2_PIX_FMT_SPCA505) );
564
+ rb_define_const( cRubyClass, "MODE_SPCA508",
565
+ INT2NUM(V4L2_PIX_FMT_SPCA508) );
566
+ rb_define_const( cRubyClass, "MODE_SPCA561",
567
+ INT2NUM(V4L2_PIX_FMT_SPCA561) );
568
+ rb_define_const( cRubyClass, "MODE_PAC207",
569
+ INT2NUM(V4L2_PIX_FMT_PAC207) );
570
+ rb_define_const( cRubyClass, "MODE_MR97310A",
571
+ INT2NUM(V4L2_PIX_FMT_MR97310A) );
572
+ rb_define_const( cRubyClass, "MODE_SQ905C",
573
+ INT2NUM(V4L2_PIX_FMT_SQ905C) );
574
+ rb_define_const( cRubyClass, "MODE_PJPG",
575
+ INT2NUM(V4L2_PIX_FMT_PJPG) );
576
+ rb_define_const( cRubyClass, "MODE_OV511",
577
+ INT2NUM(V4L2_PIX_FMT_OV511) );
578
+ rb_define_const( cRubyClass, "MODE_OV518",
579
+ INT2NUM(V4L2_PIX_FMT_OV518) );
580
+ rb_define_const( cRubyClass, "TYPE_INTEGER",
581
+ INT2NUM(V4L2_CTRL_TYPE_INTEGER) );
582
+ rb_define_const( cRubyClass, "TYPE_BOOLEAN",
583
+ INT2NUM(V4L2_CTRL_TYPE_BOOLEAN) );
584
+ rb_define_const( cRubyClass, "TYPE_MENU",
585
+ INT2NUM(V4L2_CTRL_TYPE_MENU) );
586
+ rb_define_const( cRubyClass, "TYPE_BUTTON",
587
+ INT2NUM(V4L2_CTRL_TYPE_BUTTON) );
588
+ rb_define_const( cRubyClass, "TYPE_CTRL_CLASS",
589
+ INT2NUM(V4L2_CTRL_TYPE_CTRL_CLASS) );
590
+ rb_define_const( cRubyClass, "FEATURE_BASE",
591
+ INT2NUM(V4L2_CID_BASE) );
592
+ rb_define_const( cRubyClass, "FEATURE_USER_BASE",
593
+ INT2NUM(V4L2_CID_USER_BASE) );
594
+ rb_define_const( cRubyClass, "FEATURE_PRIVATE_BASE",
595
+ INT2NUM(V4L2_CID_PRIVATE_BASE) );
596
+ rb_define_const( cRubyClass, "FEATURE_BRIGHTNESS",
597
+ INT2NUM(V4L2_CID_BRIGHTNESS) );
598
+ rb_define_const( cRubyClass, "FEATURE_CONTRAST",
599
+ INT2NUM(V4L2_CID_CONTRAST) );
600
+ rb_define_const( cRubyClass, "FEATURE_SATURATION",
601
+ INT2NUM(V4L2_CID_SATURATION) );
602
+ rb_define_const( cRubyClass, "FEATURE_HUE",
603
+ INT2NUM(V4L2_CID_HUE) );
604
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_VOLUME",
605
+ INT2NUM(V4L2_CID_AUDIO_VOLUME) );
606
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_BALANCE",
607
+ INT2NUM(V4L2_CID_AUDIO_BALANCE) );
608
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_BASS",
609
+ INT2NUM(V4L2_CID_AUDIO_BASS) );
610
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_TREBLE",
611
+ INT2NUM(V4L2_CID_AUDIO_TREBLE) );
612
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_MUTE",
613
+ INT2NUM(V4L2_CID_AUDIO_MUTE) );
614
+ rb_define_const( cRubyClass, "FEATURE_AUDIO_LOUDNESS",
615
+ INT2NUM(V4L2_CID_AUDIO_LOUDNESS) );
616
+ rb_define_const( cRubyClass, "FEATURE_BLACK_LEVEL",
617
+ INT2NUM(V4L2_CID_BLACK_LEVEL) );
618
+ rb_define_const( cRubyClass, "FEATURE_AUTO_WHITE_BALANCE",
619
+ INT2NUM(V4L2_CID_AUTO_WHITE_BALANCE) );
620
+ rb_define_const( cRubyClass, "FEATURE_DO_WHITE_BALANCE",
621
+ INT2NUM(V4L2_CID_DO_WHITE_BALANCE) );
622
+ rb_define_const( cRubyClass, "FEATURE_RED_BALANCE",
623
+ INT2NUM(V4L2_CID_RED_BALANCE) );
624
+ rb_define_const( cRubyClass, "FEATURE_BLUE_BALANCE",
625
+ INT2NUM(V4L2_CID_BLUE_BALANCE) );
626
+ rb_define_const( cRubyClass, "FEATURE_GAMMA",
627
+ INT2NUM(V4L2_CID_GAMMA) );
628
+ rb_define_const( cRubyClass, "FEATURE_WHITENESS",
629
+ INT2NUM(V4L2_CID_WHITENESS) );
630
+ rb_define_const( cRubyClass, "FEATURE_EXPOSURE",
631
+ INT2NUM(V4L2_CID_EXPOSURE) );
632
+ rb_define_const( cRubyClass, "FEATURE_AUTOGAIN",
633
+ INT2NUM(V4L2_CID_AUTOGAIN) );
634
+ rb_define_const( cRubyClass, "FEATURE_GAIN",
635
+ INT2NUM(V4L2_CID_GAIN) );
636
+ rb_define_const( cRubyClass, "FEATURE_HFLIP",
637
+ INT2NUM(V4L2_CID_HFLIP) );
638
+ rb_define_const( cRubyClass, "FEATURE_VFLIP",
639
+ INT2NUM(V4L2_CID_VFLIP) );
640
+ rb_define_const( cRubyClass, "FEATURE_HCENTER",
641
+ INT2NUM(V4L2_CID_HCENTER) );
642
+ rb_define_const( cRubyClass, "FEATURE_VCENTER",
643
+ INT2NUM(V4L2_CID_VCENTER) );
644
+ rb_define_const( cRubyClass, "FEATURE_LASTP1",
645
+ INT2NUM(V4L2_CID_LASTP1) );
646
+ rb_define_singleton_method( cRubyClass, "new", RUBY_METHOD_FUNC( wrapNew ), 1 );
461
647
  rb_define_method( cRubyClass, "close",
462
648
  RUBY_METHOD_FUNC( wrapClose ), 0 );
463
649
  rb_define_method( cRubyClass, "read",
@@ -495,17 +681,13 @@ void V4L2Input::deleteRubyObject( void *ptr )
495
681
  delete (V4L2InputPtr *)ptr;
496
682
  }
497
683
 
498
- VALUE V4L2Input::wrapNew( VALUE rbClass, VALUE rbDevice, VALUE rbWidth,
499
- VALUE rbHeight, VALUE rbPreferredTypecode )
684
+ VALUE V4L2Input::wrapNew( VALUE rbClass, VALUE rbDevice )
500
685
  {
501
686
  VALUE retVal = Qnil;
502
687
  try {
503
688
  rb_check_type( rbDevice, T_STRING );
504
- V4L2InputPtr ptr
505
- ( new V4L2Input
506
- ( StringValuePtr( rbDevice ), NUM2INT( rbWidth ),
507
- NUM2INT( rbHeight ),
508
- StringValuePtr( rbPreferredTypecode ) ) );
689
+ V4L2SelectPtr select( new V4L2Select );
690
+ V4L2InputPtr ptr( new V4L2Input( StringValuePtr( rbDevice ), select ) );
509
691
  retVal = Data_Wrap_Struct( rbClass, 0, deleteRubyObject,
510
692
  new V4L2InputPtr( ptr ) );
511
693
  } catch ( std::exception &e ) {
@@ -674,95 +856,3 @@ int V4L2Input::xioctl( int request, void *arg )
674
856
  return r;
675
857
  }
676
858
 
677
- void V4L2Input::selectPalette( int width, int height,
678
- string preferredTypecode )
679
- throw (Error)
680
- {
681
- typedef struct {
682
- const char *typecode;
683
- __u32 palette;
684
- const char *name;
685
- } PaletteEntry;
686
- PaletteEntry palette[] = {
687
- { "UYVY" , V4L2_PIX_FMT_UYVY , "UYVY" },
688
- { "YUY2" , V4L2_PIX_FMT_YUYV , "YUY2" },
689
- { "I420" , V4L2_PIX_FMT_YUV420 , "I420" },
690
- { "UBYTE" , V4L2_PIX_FMT_GREY , "UBYTE" },
691
- { "UBYTERGB", V4L2_PIX_FMT_RGB24 , "UBYTERGB" },
692
- { "MJPG" , V4L2_PIX_FMT_MJPEG , "MJPG" },
693
- { "" , V4L2_PIX_FMT_RGB332 , "RGB332" },
694
- { "" , V4L2_PIX_FMT_RGB555 , "RGB555" },
695
- { "" , V4L2_PIX_FMT_RGB565 , "RGB565" },
696
- { "" , V4L2_PIX_FMT_RGB555X , "RGB555X" },
697
- { "" , V4L2_PIX_FMT_RGB565X , "RGB565X" },
698
- { "" , V4L2_PIX_FMT_BGR24 , "BGR24" },
699
- { "" , V4L2_PIX_FMT_BGR32 , "BGR32" },
700
- { "" , V4L2_PIX_FMT_RGB32 , "RGB32" },
701
- { "" , V4L2_PIX_FMT_YVU410 , "YVU410" },
702
- { "" , V4L2_PIX_FMT_YVU420 , "YVU420" },
703
- { "" , V4L2_PIX_FMT_YUV422P , "YUV422P" },
704
- { "" , V4L2_PIX_FMT_YUV411P , "YUV411P" },
705
- { "" , V4L2_PIX_FMT_Y41P , "Y41P" },
706
- { "" , V4L2_PIX_FMT_NV12 , "NV12" },
707
- { "" , V4L2_PIX_FMT_NV21 , "NV21" },
708
- { "" , V4L2_PIX_FMT_YUV410 , "YUV410" },
709
- { "" , V4L2_PIX_FMT_YYUV , "YYUV" },
710
- { "" , V4L2_PIX_FMT_HI240 , "HI240" },
711
- // #ifdef V4L2_PIX_FMT_HM12
712
- { "" , V4L2_PIX_FMT_HM12 , "HM12" },
713
- // #endif
714
- // #ifdef V4L2_PIX_FMT_RGB444
715
- { "" , V4L2_PIX_FMT_RGB444 , "RGB444" },
716
- // #endif
717
- { "" , V4L2_PIX_FMT_RGB332 , "SBGGR8" },
718
- { "" , V4L2_PIX_FMT_JPEG , "JPEG" },
719
- { "" , V4L2_PIX_FMT_DV , "DV" },
720
- { "" , V4L2_PIX_FMT_MPEG , "MPEG" },
721
- { "" , V4L2_PIX_FMT_WNVA , "WNVA" },
722
- { "" , V4L2_PIX_FMT_SN9C10X , "SN9C10X" },
723
- { "" , V4L2_PIX_FMT_PWC1 , "PWC1" },
724
- { "" , V4L2_PIX_FMT_PWC2 , "PWC2" },
725
- { "" , V4L2_PIX_FMT_ET61X251, "ET61X251" }
726
- };
727
-
728
- memset( &m_format, 0, sizeof(m_format) );
729
- int selected = 0;
730
- ostringstream s;
731
- while ( true ) {
732
- m_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
733
- m_format.fmt.pix.field = V4L2_FIELD_NONE;
734
- m_format.fmt.pix.width = width;
735
- m_format.fmt.pix.height = height;
736
- m_format.fmt.pix.pixelformat = palette[ selected ].palette;
737
- m_format.fmt.pix.field = V4L2_FIELD_SEQ_TB;
738
- int r = xioctl( VIDIOC_S_FMT, &m_format );
739
- if ( r == 0 ) {
740
- if ( preferredTypecode == palette[ selected ].typecode ||
741
- preferredTypecode == "" ) {
742
- m_typecode = palette[ selected ].typecode;
743
- #ifndef NDEBUG
744
- cerr << "Camera-driver supports " << palette[ selected ].name
745
- << " colourspace." << endl;
746
- #endif
747
- break;
748
- } else {
749
- s << ' ' << palette[ selected ].name;
750
- };
751
- };
752
- selected++;
753
- if ( selected >= (signed)(sizeof(palette)/sizeof(PaletteEntry)) ) {
754
- ERRORMACRO( preferredTypecode == "", Error, ,
755
- "Preferred colourspace \"" << preferredTypecode
756
- << "\" not supported by camera (supported:"
757
- << s.str() << ")" );
758
- ERRORMACRO( false, Error, ,
759
- "Camera-driver doesn't offer a known video-palette" );
760
- };
761
- };
762
-
763
- ERRORMACRO( palette[ selected ].typecode[0] != '\000',
764
- Error, , "Colourspace transformation for "
765
- << palette[ selected ].name
766
- << "-images not implemented" );
767
- }
768
-
data/ext/v4l2input.hh CHANGED
@@ -24,14 +24,12 @@
24
24
  #include <linux/videodev.h>
25
25
  #include "error.hh"
26
26
  #include "frame.hh"
27
+ #include "v4l2select.hh"
27
28
 
28
29
  class V4L2Input
29
30
  {
30
31
  public:
31
- V4L2Input( const std::string &device = "/dev/video0",
32
- int width = -1, int height = -1,
33
- std::string preferredTypecode = "" )
34
- throw (Error);
32
+ V4L2Input( const std::string &device, V4L2SelectPtr select ) throw (Error);
35
33
  virtual ~V4L2Input(void);
36
34
  void close(void);
37
35
  FramePtr read(void) throw (Error);
@@ -51,9 +49,7 @@ public:
51
49
  static VALUE cRubyClass;
52
50
  static VALUE registerRubyClass( VALUE module );
53
51
  static void deleteRubyObject( void *ptr );
54
- static VALUE wrapNew( VALUE rbClass, VALUE rbDevice,
55
- VALUE rbWidth, VALUE rbHeight,
56
- VALUE rbPreferredTypecode );
52
+ static VALUE wrapNew( VALUE rbClass, VALUE rbDevice );
57
53
  static VALUE wrapClose( VALUE rbSelf );
58
54
  static VALUE wrapRead( VALUE rbSelf );
59
55
  static VALUE wrapStatus( VALUE rbSelf );
@@ -71,8 +67,6 @@ public:
71
67
  static VALUE wrapFeatureDefaultValue( VALUE rbSelf, VALUE rbId );
72
68
  protected:
73
69
  int xioctl( int request, void *arg );
74
- void selectPalette( int width, int height,
75
- std::string preferredTypecode ) throw (Error);
76
70
  std::string m_device;
77
71
  int m_fd;
78
72
  enum { IO_READ, IO_MMAP, IO_USERPTR } m_io;
data/ext/v4l2select.cc ADDED
@@ -0,0 +1,72 @@
1
+ /* HornetsEye - Computer Vision with Ruby
2
+ Copyright (C) 2006, 2007, 2008, 2009, 2010 Jan Wedekind
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ #include "rubyinc.hh"
17
+ #include "v4l2select.hh"
18
+
19
+ V4L2Select::V4L2Select(void) throw (Error):
20
+ m_rbArray(rb_ary_new())
21
+ {
22
+ }
23
+
24
+ V4L2Select::~V4L2Select(void)
25
+ {
26
+ }
27
+
28
+ void V4L2Select::add( unsigned int coding, unsigned int width, unsigned int height )
29
+ {
30
+ rb_ary_push( m_rbArray, rb_ary_new3( 3, INT2NUM( coding ), INT2NUM( width ),
31
+ INT2NUM( height ) ) );
32
+ }
33
+
34
+ static VALUE yield( VALUE arg )
35
+ {
36
+ return rb_yield( arg );
37
+ }
38
+
39
+ unsigned int V4L2Select::make(void) throw (Error)
40
+ {
41
+ int error;
42
+ VALUE rbRetVal = rb_protect( yield, m_rbArray, &error );
43
+ if ( error ) {
44
+ VALUE rbError = rb_funcall( rb_gv_get( "$!" ), rb_intern( "message" ), 0 );
45
+ ERRORMACRO( false, Error, , "Error in block to \"V4L2Input.new\": "
46
+ << StringValuePtr( rbError ) );
47
+ };
48
+ ERRORMACRO( TYPE( rbRetVal ) == T_FIXNUM, Error, , "Block must return a value of "
49
+ "type 'Fixnum'" );
50
+ return NUM2UINT(rbRetVal);
51
+ }
52
+
53
+ unsigned int V4L2Select::coding( unsigned int selection )
54
+ {
55
+ return NUM2INT( RARRAY_PTR( RARRAY_PTR(m_rbArray)[ selection ] )[ 0 ] );
56
+ }
57
+
58
+ unsigned int V4L2Select::width( unsigned int selection )
59
+ {
60
+ return NUM2INT( RARRAY_PTR( RARRAY_PTR(m_rbArray)[ selection ] )[ 1 ] );
61
+ }
62
+
63
+ unsigned int V4L2Select::height( unsigned int selection )
64
+ {
65
+ return NUM2INT( RARRAY_PTR( RARRAY_PTR(m_rbArray)[ selection ] )[ 2 ] );
66
+ }
67
+
68
+ VALUE V4L2Select::wrapRescue( VALUE rbValue )
69
+ {
70
+ return rbValue;
71
+ }
72
+
data/ext/v4l2select.hh ADDED
@@ -0,0 +1,41 @@
1
+ /* HornetsEye - Computer Vision with Ruby
2
+ Copyright (C) 2006, 2007, 2008, 2009, 2010 Jan Wedekind
3
+
4
+ This program is free software: you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation, either version 3 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
+ #ifndef HORNETSEYE_V4L2SELECT_HH
17
+ #define HORNETSEYE_V4L2SELECT_HH
18
+
19
+ #include <boost/smart_ptr.hpp>
20
+ #include <errno.h>
21
+ #include "error.hh"
22
+
23
+ class V4L2Select
24
+ {
25
+ public:
26
+ V4L2Select(void) throw (Error);
27
+ virtual ~V4L2Select(void);
28
+ void add( unsigned int coding, unsigned int width, unsigned int height );
29
+ unsigned int make(void) throw (Error);
30
+ unsigned int coding( unsigned int selection );
31
+ unsigned int width( unsigned int selection );
32
+ unsigned int height( unsigned int selection );
33
+ static VALUE wrapRescue( VALUE rbValue );
34
+ protected:
35
+ VALUE m_rbArray;
36
+ };
37
+
38
+ typedef boost::shared_ptr< V4L2Select > V4L2SelectPtr;
39
+
40
+ #endif
41
+
@@ -23,9 +23,27 @@ module Hornetseye
23
23
 
24
24
  alias_method :orig_new, :new
25
25
 
26
- def new( device = '/dev/video0', width = -1, height = -1,
27
- preferred_colourspace = '' )
28
- orig_new device, width, height, preferred_colourspace.to_s
26
+ def new( device = '/dev/video0', &action )
27
+ orig_new device do |modes|
28
+ map = { MODE_UYVY => UYVY,
29
+ MODE_YUYV => YUY2,
30
+ MODE_YUV420 => I420,
31
+ MODE_GREY => UBYTE,
32
+ MODE_RGB24 => UBYTERGB }
33
+ frame_types, index = [], []
34
+ modes.each_with_index do |mode,i|
35
+ target = map[ mode.first ]
36
+ if target
37
+ frame_types.push Hornetseye::Frame( target, *mode[ 1 .. 2 ] )
38
+ index.push i
39
+ end
40
+ end
41
+ desired = action.call frame_types
42
+ unless frame_types.member? desired
43
+ raise "Frame type #{desired} not supported by camera"
44
+ end
45
+ index[ frame_types.index( desired ) ]
46
+ end
29
47
  end
30
48
 
31
49
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jan Wedekind
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-07 00:00:00 +01:00
17
+ date: 2010-11-20 00:00:00 +00:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -88,10 +88,12 @@ files:
88
88
  - lib/hornetseye-v4l2/v4l2input.rb
89
89
  - lib/hornetseye_v4l2_ext.rb
90
90
  - ext/v4l2input.cc
91
+ - ext/v4l2select.cc
91
92
  - ext/init.cc
92
93
  - ext/frame.cc
93
94
  - ext/frame.hh
94
95
  - ext/rubytools.hh
96
+ - ext/v4l2select.hh
95
97
  - ext/v4l2input.hh
96
98
  - ext/rubyinc.hh
97
99
  - ext/error.hh