core/vidl/vidl_dc1394_istream.cxx
Go to the documentation of this file.
00001 // This is core/vidl/vidl_dc1394_istream.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author Matt Leotta
00008 // \date   6 Jan 2005
00009 //
00010 //-----------------------------------------------------------------------------
00011 
00012 #include "vidl_dc1394_istream.h"
00013 #include "vidl_iidc1394_params.h"
00014 #include "vidl_pixel_format.h"
00015 #include "vidl_frame.h"
00016 
00017 #include <dc1394/control.h>
00018 #include <dc1394/utils.h>
00019 
00020 //--------------------------------------------------------------------------------
00021 // Anonymous namespace
00022 namespace {
00023 
00024 vidl_iidc1394_params::feature_options
00025 dc1394_feature_to_vidl(const dc1394feature_info_t& f_old)
00026 {
00027   vidl_iidc1394_params::feature_options f;
00028   f.id = static_cast<vidl_iidc1394_params::feature_t>(f_old.id - DC1394_FEATURE_MIN);
00029   f.active_mode = static_cast<vidl_iidc1394_params::feature_mode_t>
00030                   (f_old.current_mode - DC1394_FEATURE_MODE_MIN);
00031 
00032   for (unsigned int i=0; i<f_old.modes.num; ++i) {
00033     f.available_modes.push_back(static_cast<vidl_iidc1394_params::feature_mode_t>
00034                                 (f_old.modes.modes[i] - DC1394_FEATURE_MODE_MIN) );
00035   }
00036 
00037   f.available = f_old.available;
00038   f.absolute_capable = f_old.absolute_capable;
00039   f.readout_capable = f_old.readout_capable;
00040   f.on_off_capable = f_old.on_off_capable;
00041   f.polarity_capable = f_old.polarity_capable;
00042   f.is_on = f_old.is_on;
00043 
00044   f.min = f_old.min;
00045   f.max = f_old.max;
00046   f.value = f_old.value;
00047   f.BU_value = f_old.BU_value;
00048   f.RV_value = f_old.RV_value;
00049   f.B_value = f_old.B_value;
00050   f.R_value = f_old.R_value;
00051   f.G_value = f_old.G_value;
00052   f.target_value = f_old.target_value;
00053 
00054   f.abs_control = f_old.abs_control;
00055   f.abs_value = f_old.abs_value;
00056   f.abs_max = f_old.abs_max;
00057   f.abs_min = f_old.abs_min;
00058 
00059   return f;
00060 }
00061 
00062 dc1394feature_info_t
00063 vidl_feature_to_dc1394(const vidl_iidc1394_params::feature_options& f_old)
00064 {
00065   dc1394feature_info_t f;
00066   f.id = static_cast<dc1394feature_t>(f_old.id + DC1394_FEATURE_MIN);
00067   f.current_mode = static_cast<dc1394feature_mode_t>
00068                     (f_old.active_mode + DC1394_FEATURE_MODE_MIN);
00069 
00070   for (unsigned int i=0; i<f_old.available_modes.size(); ++i) {
00071     f.modes.modes[i] = static_cast<dc1394feature_mode_t>
00072                         (f_old.available_modes[i] + DC1394_FEATURE_MODE_MIN);
00073   }
00074 
00075   f.available = f_old.available?DC1394_TRUE:DC1394_FALSE;
00076   f.absolute_capable = f_old.absolute_capable?DC1394_TRUE:DC1394_FALSE;
00077   f.readout_capable = f_old.readout_capable?DC1394_TRUE:DC1394_FALSE;
00078   f.on_off_capable = f_old.on_off_capable?DC1394_TRUE:DC1394_FALSE;
00079   f.polarity_capable = f_old.polarity_capable?DC1394_TRUE:DC1394_FALSE;
00080   f.is_on = f_old.is_on?DC1394_ON:DC1394_OFF;
00081 
00082   f.min = f_old.min;
00083   f.max = f_old.max;
00084   f.value = f_old.value;
00085   f.BU_value = f_old.BU_value;
00086   f.RV_value = f_old.RV_value;
00087   f.B_value = f_old.B_value;
00088   f.R_value = f_old.R_value;
00089   f.G_value = f_old.G_value;
00090   f.target_value = f_old.target_value;
00091 
00092   f.abs_control = f_old.abs_control?DC1394_ON:DC1394_OFF;
00093   f.abs_value = f_old.abs_value;
00094   f.abs_max = f_old.abs_max;
00095   f.abs_min = f_old.abs_min;
00096 
00097   return f;
00098 }
00099 
00100 }; // anonymous namespace
00101 
00102 //--------------------------------------------------------------------------------
00103 struct vidl_dc1394_istream::pimpl
00104 {
00105   pimpl()
00106   : vid_index_( unsigned(-1) ),
00107     dc1394_data_(NULL),
00108     camera_info_(NULL),
00109     max_speed_(DC1394_ISO_SPEED_400),
00110     b_mode_(false),
00111     pixel_format_(VIDL_PIXEL_FORMAT_UNKNOWN),
00112     width_(0),
00113     height_(0),
00114     framerate_(0.0),
00115     cur_frame_(NULL),
00116     dc1394frame_(NULL),
00117     cur_frame_valid_(false)
00118   {
00119   }
00120 
00121   unsigned int vid_index_;
00122 
00123   dc1394_t * dc1394_data_;
00124 
00125   dc1394camera_t* camera_info_;
00126 
00127   int max_speed_;
00128 
00129   bool b_mode_;
00130 
00131   vidl_pixel_format pixel_format_;
00132 
00133   unsigned int width_;
00134 
00135   unsigned int height_;
00136 
00137   double framerate_;
00138 
00139   //: The last successfully decoded frame.
00140   mutable vidl_frame_sptr cur_frame_;
00141 
00142   dc1394video_frame_t *dc1394frame_;
00143 
00144   bool cur_frame_valid_;
00145 };
00146 
00147 
00148 //--------------------------------------------------------------------------------
00149 
00150 //: Constructor
00151 vidl_dc1394_istream::
00152 vidl_dc1394_istream()
00153   : is_( new vidl_dc1394_istream::pimpl )
00154 {
00155   is_->dc1394_data_ = dc1394_new();
00156 }
00157 
00158 
00159 //: Destructor
00160 vidl_dc1394_istream::
00161 ~vidl_dc1394_istream()
00162 {
00163   close();
00164   dc1394_free(is_->dc1394_data_);
00165   delete is_;
00166 }
00167 
00168 //: Open a new stream using a filename
00169 bool
00170 vidl_dc1394_istream::
00171 open(unsigned int num_dma_buffers,
00172      bool drop_frames,
00173      const vidl_iidc1394_params& params)
00174 {
00175   // Close any currently opened file
00176   close();
00177 
00178   // FIXME - where is this used in the new API?
00179   //dc1394ring_buffer_policy_t rb_policy = drop_frames? DC1394_RING_BUFFER_LAST: DC1394_RING_BUFFER_NEXT;
00180 
00181   is_->camera_info_ = dc1394_camera_new (is_->dc1394_data_, params.guid_);
00182   if (!is_->camera_info_) {
00183     vcl_cerr << "Warning, failed to initialize camera with guid " << vcl_hex << params.guid_ << vcl_endl;
00184     return false;
00185   }
00186 
00187   dc1394operation_mode_t op_mode = params.b_mode_ ? DC1394_OPERATION_MODE_1394B : DC1394_OPERATION_MODE_LEGACY;
00188   if ( dc1394_video_set_operation_mode(is_->camera_info_, op_mode) != DC1394_SUCCESS) {
00189     vcl_cerr << "Failed to set camera in b mode\n";
00190     close();
00191     return false;
00192   }
00193 
00194   if (dc1394_video_set_iso_speed(is_->camera_info_, dc1394speed_t(params.speed_)) != DC1394_SUCCESS) {
00195     vcl_cerr << "Failed to set iso channel and speed.\n";
00196     close();
00197     return false;
00198   }
00199 
00200   if (dc1394_video_set_mode(is_->camera_info_, dc1394video_mode_t(params.video_mode_)) != DC1394_SUCCESS) {
00201     vcl_cerr << "Failed to set video mode.\n";
00202     close();
00203     return false;
00204   }
00205 
00206   if (dc1394_video_set_framerate(is_->camera_info_, dc1394framerate_t(params.frame_rate_)) != DC1394_SUCCESS) {
00207     vcl_cerr << "Failed to set frame rate.\n";
00208     close();
00209     return false;
00210   }
00211   //else
00212   //  is_->camera_info_->framerate = dc1394framerate_t(params.frame_rate_);
00213 
00214   for (unsigned int i=0; i<params.features_.size(); ++i)
00215   {
00216     dc1394feature_info_t f = vidl_feature_to_dc1394(params.features_[i]);
00217     // Enable/Disable a feature
00218     if ( dc1394_feature_set_power(is_->camera_info_, f.id, f.is_on?DC1394_ON:DC1394_OFF) != DC1394_SUCCESS) {
00219       vcl_cerr << "Failed to " << (f.is_on ? "enable" : "disable") <<" feature \""
00220                << vidl_iidc1394_params::feature_string(params.features_[i].id)
00221                << '\n';
00222       return false;
00223     }
00224 
00225     // Set the feature mode
00226     dc1394feature_mode_t old_mode;
00227     if ( dc1394_feature_get_mode(is_->camera_info_, f.id, &old_mode) == DC1394_SUCCESS &&
00228          old_mode != f.current_mode ) {
00229       if ( dc1394_feature_set_mode(is_->camera_info_, f.id, f.current_mode) != DC1394_SUCCESS) {
00230         vcl_cerr << "Failed to set mode of feature \""
00231                  << vidl_iidc1394_params::feature_string(params.features_[i].id)
00232                  << "\" to " << vidl_iidc1394_params::feature_mode_string(params.features_[i].active_mode) << '\n';
00233         return false;
00234       }
00235     }
00236 
00237 
00238     // Set the feature value(s)
00239     switch (params.features_[i].id)
00240     {
00241      case vidl_iidc1394_params::FEATURE_WHITE_BALANCE:
00242       if ( dc1394_feature_whitebalance_set_value(is_->camera_info_, f.BU_value, f.RV_value) != DC1394_SUCCESS) {
00243         vcl_cerr << "Failed to set feature \"White Balance\" to "<< f.BU_value<<", "<<f.RV_value <<'\n';
00244         close();
00245         return false;
00246       }
00247       break;
00248     case vidl_iidc1394_params::FEATURE_TEMPERATURE:
00249       if ( dc1394_feature_temperature_set_value(is_->camera_info_, f.target_value) != DC1394_SUCCESS) {
00250         vcl_cerr << "Failed to set feature \"Temperature\" to "<< f.target_value<<'\n';
00251         close();
00252         return false;
00253       }
00254       break;
00255     default:
00256       if ( f.abs_control ) {
00257         if ( dc1394_feature_set_absolute_value(is_->camera_info_, f.id, f.abs_value) != DC1394_SUCCESS) {
00258           vcl_cerr << "Failed to set feature \""
00259                    << vidl_iidc1394_params::feature_string(params.features_[i].id)
00260                    << "\" to absolute value "<< f.value <<'\n';
00261           close();
00262           return false;
00263         }
00264       }
00265       else if ( dc1394_feature_set_value(is_->camera_info_, f.id, f.value) != DC1394_SUCCESS) {
00266         vcl_cerr << "Failed to set feature \""
00267                  << vidl_iidc1394_params::feature_string(params.features_[i].id)
00268                  << "\" to "<< f.value <<'\n';
00269         close();
00270         return false;
00271       }
00272     }
00273   }
00274 
00275 
00276   if (dc1394_capture_setup(is_->camera_info_, num_dma_buffers,
00277                            DC1394_CAPTURE_FLAGS_DEFAULT) != DC1394_SUCCESS) {
00278     vcl_cerr << "Failed to setup DMA capture.\n";
00279     return false;
00280   }
00281 
00282 
00283   is_->pixel_format_ = vidl_iidc1394_params::pixel_format(params.video_mode_);
00284   vidl_iidc1394_params::resolution(params.video_mode_,is_->width_,is_->height_);
00285   is_->framerate_ = vidl_iidc1394_params::frame_rate_val(params.frame_rate_);
00286 
00287   // turn on the camera power
00288   dc1394switch_t pwr;
00289   if (dc1394_video_get_transmission(is_->camera_info_, &pwr) == DC1394_SUCCESS) {
00290     if (pwr == DC1394_ON ) {
00291       dc1394_video_set_transmission(is_->camera_info_, DC1394_OFF);
00292       vcl_cerr << "power already on\n";
00293     }
00294     if (dc1394_video_set_transmission(is_->camera_info_, DC1394_ON) == DC1394_SUCCESS) {
00295       vcl_cerr << "power turned on\n";
00296     }
00297     else {
00298       vcl_cerr << "unable to power on\n";
00299       return false;
00300     }
00301     return true;
00302   }
00303   else {
00304     vcl_cerr << "unable to start camera iso transmission\n";
00305     close();
00306     return false;
00307   }
00308 
00309   return true;
00310 }
00311 
00312 
00313 //: Close the stream
00314 void
00315 vidl_dc1394_istream::
00316 close()
00317 {
00318   if (is_->camera_info_) {
00319     // turn off the camera power
00320     dc1394switch_t pwr;
00321     if (dc1394_video_get_transmission(is_->camera_info_, &pwr) == DC1394_SUCCESS &&
00322         pwr == DC1394_ON) {
00323       dc1394_video_set_transmission(is_->camera_info_, DC1394_OFF);
00324     }
00325 
00326     dc1394_capture_stop(is_->camera_info_);
00327     dc1394_camera_free(is_->camera_info_);
00328     is_->camera_info_ = NULL;
00329   }
00330   is_->vid_index_ = unsigned(-1);
00331   is_->pixel_format_ = VIDL_PIXEL_FORMAT_UNKNOWN;
00332   is_->width_ = 0;
00333   is_->height_ = 0;
00334   is_->framerate_ = 0.0;
00335 }
00336 
00337 
00338 //: Probe the bus to determine the valid parameter options
00339 bool
00340 vidl_dc1394_istream::
00341 valid_params(vidl_iidc1394_params::valid_options& options)
00342 {
00343   dc1394_t * d = dc1394_new();
00344   dc1394camera_list_t * list;
00345 
00346   // enumerate the cameras
00347   dc1394error_t err = dc1394_camera_enumerate(d, &list);
00348 
00349   if (err) {
00350     vcl_cerr << "error finding cameras: "
00351              << dc1394_error_get_string(err) << vcl_endl;
00352     dc1394_camera_free_list (list);
00353     dc1394_free(d);
00354     return false;
00355   }
00356 
00357   // No cameras found
00358   if (list->num == 0) {
00359     options.cameras.clear();
00360     dc1394_camera_free_list (list);
00361     dc1394_free(d);
00362     return true;
00363   }
00364 
00365   options.cameras.resize(list->num);
00366 
00367   // create a list of cameras
00368   for (unsigned int i=0; i<list->num; ++i) {
00369     dc1394camera_t *camera = dc1394_camera_new (d, list->ids[i].guid);
00370     if (!camera) {
00371       vcl_cerr << "Warning, failed to initialize camera with guid " << vcl_hex << list->ids[i].guid << vcl_endl;
00372       continue;
00373     }
00374 
00375     options.cameras[i].guid = camera->guid;
00376     options.cameras[i].vendor = camera->vendor;
00377     options.cameras[i].model = camera->model;
00378 
00379     dc1394video_mode_t video_mode;
00380     if ( dc1394_video_get_mode(camera,&video_mode) == DC1394_SUCCESS )
00381       options.cameras[i].curr_mode = static_cast<vidl_iidc1394_params::video_mode_t>(video_mode);
00382 
00383     dc1394framerate_t framerate;
00384     if ( dc1394_video_get_framerate(camera,&framerate) == DC1394_SUCCESS )
00385       options.cameras[i].curr_frame_rate = static_cast<vidl_iidc1394_params::frame_rate_t>(framerate);
00386 
00387     dc1394operation_mode_t op_mode;
00388     if ( dc1394_video_get_operation_mode(camera, &op_mode) == DC1394_SUCCESS)
00389       options.cameras[i].b_mode = (op_mode == DC1394_OPERATION_MODE_1394B);
00390 
00391     dc1394speed_t iso_speed;
00392     if ( dc1394_video_get_iso_speed(camera, &iso_speed) == DC1394_SUCCESS)
00393       options.cameras[i].speed = static_cast<vidl_iidc1394_params::speed_t>(iso_speed);
00394 
00395     dc1394video_modes_t modes;
00396     if ( dc1394_video_get_supported_modes(camera, &modes ) <0 ) {
00397       vcl_cerr << "Could not find any supported video modes\n";
00398       dc1394_camera_free_list (list);
00399       dc1394_free(d);
00400       return false;
00401     }
00402     //const vidl_iidc1394_params::valid_options::valid_modes& m =
00403     options.cameras[i].modes.resize(modes.num);
00404     for (unsigned int j=0; j<modes.num; ++j)
00405     {
00406       options.cameras[i].modes[j].mode = (vidl_iidc1394_params::video_mode_t) modes.modes[j];
00407       unsigned int format = vidl_iidc1394_params::video_format_val(options.cameras[i].modes[j].mode);
00408       if (format > 5)
00409         continue;
00410       dc1394framerates_t framerates;
00411       dc1394_video_get_supported_framerates(camera, modes.modes[j], &framerates);
00412       options.cameras[i].modes[j].frame_rates.resize(framerates.num);
00413       for (unsigned int k=0; k<framerates.num; ++k) {
00414         options.cameras[i].modes[j].frame_rates[k] = (vidl_iidc1394_params::frame_rate_t)framerates.framerates[k];
00415       }
00416     }
00417     dc1394featureset_t features;
00418     if (dc1394_feature_get_all(camera, &features) < 0) {
00419       vcl_cerr << "Could not find any camera control features\n";
00420       dc1394_camera_free_list (list);
00421       dc1394_free(d);
00422       return false;
00423     }
00424     for (unsigned int k= DC1394_FEATURE_MIN, j= 0; k <= DC1394_FEATURE_MAX; k++, j++)  {
00425       const dc1394feature_info_t& f = features.feature[j];
00426       if (!f.available)
00427         continue;
00428       options.cameras[i].features.push_back(dc1394_feature_to_vidl(f));
00429       vcl_cout << "feature: "<< dc1394_feature_get_string(f.id) << vcl_endl;
00430     }
00431     dc1394_feature_print_all(&features, stdout);
00432 
00433     dc1394_camera_free(camera);
00434   }
00435 
00436 
00437   dc1394_camera_free_list (list);
00438   dc1394_free(d);
00439 
00440   return true;
00441 }
00442 
00443 
00444 //: Return true if the stream is open for reading
00445 bool
00446 vidl_dc1394_istream::
00447 is_open() const
00448 {
00449   return bool(is_->camera_info_);
00450 }
00451 
00452 
00453 //: Return true if the stream is in a valid state
00454 bool
00455 vidl_dc1394_istream::
00456 is_valid() const
00457 {
00458   return is_open() && bool(is_->dc1394frame_);
00459 }
00460 
00461 
00462 //: Return true if the stream support seeking
00463 bool
00464 vidl_dc1394_istream::
00465 is_seekable() const
00466 {
00467   return false;
00468 }
00469 
00470 
00471 //: Return the number of frames if known
00472 //  returns -1 for non-seekable streams
00473 int
00474 vidl_dc1394_istream::
00475 num_frames() const
00476 {
00477   return -1;
00478 }
00479 
00480 
00481 //: Return the current frame number
00482 unsigned int
00483 vidl_dc1394_istream::
00484 frame_number() const
00485 {
00486   return is_->vid_index_;
00487 }
00488 
00489 
00490 //: Return the width of each frame
00491 unsigned int
00492 vidl_dc1394_istream::
00493 width() const
00494 {
00495   return is_->width_;
00496 }
00497 
00498 
00499 //: Return the height of each frame
00500 unsigned int
00501 vidl_dc1394_istream::
00502 height() const
00503 {
00504   return is_->height_;
00505 }
00506 
00507 
00508 //: Return the pixel format
00509 vidl_pixel_format
00510 vidl_dc1394_istream::
00511 format() const
00512 {
00513   return is_->pixel_format_;
00514 }
00515 
00516 
00517 //: Return the frame rate (0.0 if unspecified)
00518 double
00519 vidl_dc1394_istream::
00520 frame_rate() const
00521 {
00522   return is_->framerate_;
00523 }
00524 
00525 
00526 //: Return the duration in seconds (0.0 if unknown)
00527 double
00528 vidl_dc1394_istream::
00529 duration() const
00530 {
00531   return 0.0;
00532 }
00533 
00534 
00535 //: Advance to the next frame (but don't acquire an image)
00536 bool
00537 vidl_dc1394_istream::
00538 advance()
00539 {
00540   ++is_->vid_index_;
00541   is_->cur_frame_valid_ = false;
00542 
00543   if (is_->dc1394frame_)
00544     dc1394_capture_enqueue(is_->camera_info_, is_->dc1394frame_);
00545 
00546   if (dc1394_capture_dequeue(is_->camera_info_, DC1394_CAPTURE_POLICY_WAIT, &(is_->dc1394frame_))!=DC1394_SUCCESS) {
00547     vcl_cerr << "capture failed\n";
00548     return false;
00549   }
00550   return true;
00551 }
00552 
00553 
00554 //: Read the next frame from the stream
00555 vidl_frame_sptr
00556 vidl_dc1394_istream::read_frame()
00557 {
00558   if (advance())
00559     return current_frame();
00560   return NULL;
00561 }
00562 
00563 
00564 //: Return the current frame in the stream
00565 vidl_frame_sptr
00566 vidl_dc1394_istream::current_frame()
00567 {
00568   // Quick return if the stream isn't valid
00569   if ( !is_valid() ) {
00570     return NULL;
00571   }
00572 
00573 
00574   if (!is_->cur_frame_valid_) {
00575     if (is_->cur_frame_)
00576       is_->cur_frame_->invalidate();
00577 
00578     is_->cur_frame_ = new vidl_shared_frame(is_->dc1394frame_->image,
00579                                             is_->dc1394frame_->size[0],
00580                                             is_->dc1394frame_->size[1],
00581                                             is_->pixel_format_);
00582 
00583     is_->cur_frame_valid_ = true;
00584   }
00585 
00586   return is_->cur_frame_;
00587 }
00588 
00589 
00590 //: Seek to the given frame number
00591 // \returns true if successful
00592 bool
00593 vidl_dc1394_istream::
00594 seek_frame(unsigned int frame)
00595 {
00596   return false;
00597 }
00598