core/vidl/gui/vidl_gui_param_dialog.cxx
Go to the documentation of this file.
00001 // This is core/vidl/gui/vidl_gui_param_dialog.cxx
00002 #include "vidl_gui_param_dialog.h"
00003 //:
00004 // \file
00005 // \author Matt Leotta
00006 
00007 #include <vcl_iostream.h>
00008 #include <vcl_sstream.h>
00009 #include <vil/vil_file_format.h>
00010 #include <vgui/vgui_error_dialog.h>
00011 #include <vgui/vgui_dialog.h>
00012 
00013 
00014 #include <vidl/vidl_config.h>
00015 #include <vidl/vidl_image_list_istream.h>
00016 #include <vidl/vidl_image_list_ostream.h>
00017 
00018 #if VIDL_HAS_FFMPEG
00019 #include <vidl/vidl_ffmpeg_istream.h>
00020 #include <vidl/vidl_ffmpeg_ostream.h>
00021 #include <vidl/vidl_ffmpeg_ostream_params.h>
00022 #endif
00023 
00024 #if VIDL_HAS_DC1394
00025 #include <vidl/vidl_dc1394_istream.h>
00026 #endif
00027 
00028 #if VIDL_HAS_VIDEODEV2
00029 #include <vidl/vidl_v4l2_devices.h>
00030 #include <vidl/vidl_v4l2_istream.h>
00031 #endif
00032 
00033 //: Use vgui dialogs to prompt the user for parameters and open an istream
00034 vidl_istream* vidl_gui_open_istream_dialog()
00035 {
00036   enum stream_type {IMAGE_LIST, FFMPEG, DC1394, V4L2};
00037   vgui_dialog dlg("Select an Input Stream Type");
00038 
00039   vcl_vector<vcl_string> choices;
00040   vcl_vector<int> choice_codes;
00041   choices.push_back( "Image List" ); choice_codes.push_back(IMAGE_LIST);
00042 #if VIDL_HAS_FFMPEG
00043   choices.push_back( "FFMPEG" ); choice_codes.push_back(FFMPEG);
00044 #endif
00045 #if VIDL_HAS_DC1394
00046   choices.push_back( "dc1394" ); choice_codes.push_back(DC1394);
00047 #endif
00048 #if VIDL_HAS_VIDEODEV2
00049   choices.push_back( "Video for Linux 2" ); choice_codes.push_back(V4L2);
00050 #endif
00051 
00052   static int idx = 0;
00053   dlg.choice("Stream Type",choices,idx);
00054 
00055   if (!dlg.ask())
00056     return NULL;
00057 
00058   switch (choice_codes[idx]) {
00059     case IMAGE_LIST:
00060       return vidl_gui_param_dialog::image_list_istream();
00061 #if VIDL_HAS_FFMPEG
00062     case FFMPEG:
00063       return vidl_gui_param_dialog::ffmpeg_istream();
00064 #endif
00065 #if VIDL_HAS_DC1394
00066     case DC1394:
00067       return vidl_gui_param_dialog::dc1394_istream();
00068 #endif
00069 #if VIDL_HAS_VIDEODEV2
00070     case V4L2:
00071       return vidl_gui_param_dialog::v4l2_istream();
00072 #endif
00073     default:
00074       break;
00075   }
00076 
00077   vgui_error_dialog("Invalid input stream type");
00078   return NULL;
00079 }
00080 
00081 
00082 //: Use vgui dialogs to prompt the user for parameters and open an ostream
00083 vidl_ostream* vidl_gui_open_ostream_dialog()
00084 {
00085   enum stream_type {IMAGE_LIST, FFMPEG};
00086   vgui_dialog dlg("Select an Output Stream Type");
00087 
00088   vcl_vector<vcl_string> choices;
00089   vcl_vector<int> choice_codes;
00090   choices.push_back( "Image List" ); choice_codes.push_back(IMAGE_LIST);
00091 #if VIDL_HAS_FFMPEG
00092   choices.push_back( "FFMPEG" ); choice_codes.push_back(FFMPEG);
00093 #endif
00094 
00095   static int idx = 0;
00096   dlg.choice("Stream Type",choices,idx);
00097 
00098   if (!dlg.ask())
00099     return NULL;
00100 
00101   switch (choice_codes[idx]) {
00102     case IMAGE_LIST:
00103       return vidl_gui_param_dialog::image_list_ostream();
00104 #if VIDL_HAS_FFMPEG
00105     case FFMPEG:
00106       return vidl_gui_param_dialog::ffmpeg_ostream();
00107 #endif
00108     default:
00109       break;
00110   }
00111 
00112   vgui_error_dialog("Invalid output stream type");
00113   return NULL;
00114 }
00115 
00116 
00117 //-----------------------------------------------------------------------------
00118 //: Use vgui dialogs to open an image list istream
00119 //-----------------------------------------------------------------------------
00120 vidl_image_list_istream* vidl_gui_param_dialog::image_list_istream()
00121 {
00122   vgui_dialog dlg("Open Image List Input Stream");
00123   static vcl_string image_filename = "*";
00124   static vcl_string ext = "*";
00125 
00126   dlg.message("Specify the images using a file glob");
00127   dlg.file("Filename:", ext, image_filename);
00128   if (!dlg.ask())
00129     return NULL;
00130 
00131   vidl_image_list_istream* i_stream = new vidl_image_list_istream(image_filename);
00132   if (!i_stream || !i_stream->is_open()) {
00133     vgui_error_dialog("Failed to open the input stream");
00134     delete i_stream;
00135     return NULL;
00136   }
00137 
00138   return i_stream;
00139 }
00140 
00141 
00142 //-----------------------------------------------------------------------------
00143 //: Use vgui dialogs to open an image list ostream
00144 //-----------------------------------------------------------------------------
00145 vidl_image_list_ostream* vidl_gui_param_dialog::image_list_ostream()
00146 {
00147   vgui_dialog dlg("Open Output Image List Stream");
00148   static vcl_string directory = "";
00149   static vcl_string name_format = "%05u";
00150   static vcl_string ext = "*";
00151 
00152   dlg.file("Directory", ext, directory);
00153   vcl_string info = "Use a \'printf\' style format string to insert\n";
00154   info += "the unsigned integer file index into the file name";
00155   dlg.message(info.c_str());
00156   dlg.field("Filename Format", name_format);
00157 
00158   // provide a list of choices for valid file formats
00159   static vcl_vector<vcl_string> fmt_choices;
00160   if (fmt_choices.empty()) {
00161     for (vil_file_format** p = vil_file_format::all(); *p; ++p)
00162       fmt_choices.push_back((*p)->tag());
00163   }
00164   static int fmt_idx = 0;
00165   dlg.choice("Image File Format",fmt_choices,fmt_idx);
00166 
00167   static unsigned int start_index = 0;
00168   dlg.field("Starting Index", start_index);
00169 
00170   if (!dlg.ask())
00171     return NULL;
00172 
00173   vidl_image_list_ostream* o_stream = new vidl_image_list_ostream(directory,
00174                                                                   name_format,
00175                                                                   fmt_choices[fmt_idx],
00176                                                                   start_index);
00177 
00178   if (!o_stream || !o_stream->is_open()) {
00179     vgui_error_dialog("Failed to create output image list stream");
00180     delete o_stream;
00181     return NULL;
00182   }
00183 
00184   return o_stream;
00185 }
00186 
00187 
00188 //-----------------------------------------------------------------------------
00189 //: Use vgui dialogs to open a FFMPEG istream
00190 //-----------------------------------------------------------------------------
00191 vidl_ffmpeg_istream* vidl_gui_param_dialog::ffmpeg_istream()
00192 {
00193 #if VIDL_HAS_FFMPEG
00194   vgui_dialog dlg("Open FFMPEG Input Stream");
00195   static vcl_string image_filename = "";
00196   static vcl_string ext = "*";
00197 
00198   dlg.file("Filename:", ext, image_filename);
00199   if (!dlg.ask())
00200     return NULL;
00201 
00202   vidl_ffmpeg_istream* i_stream = new vidl_ffmpeg_istream(image_filename);
00203   if (!i_stream || !i_stream->is_open()) {
00204     vgui_error_dialog("Failed to open the input stream");
00205     delete i_stream;
00206     return NULL;
00207   }
00208   return i_stream;
00209 
00210 #else // VIDL_HAS_FFMPEG
00211   vgui_error_dialog("FFMPEG support not compiled in");
00212   return NULL;
00213 #endif // VIDL_HAS_FFMPEG
00214 }
00215 
00216 
00217 //-----------------------------------------------------------------------------
00218 //: Use vgui dialogs to open a FFMPEG ostream
00219 //-----------------------------------------------------------------------------
00220 vidl_ffmpeg_ostream* vidl_gui_param_dialog::ffmpeg_ostream()
00221 {
00222 #if VIDL_HAS_FFMPEG
00223   vgui_dialog dlg("Open FFMPEG Output Stream");
00224   static vcl_string file = "";
00225   static vcl_string ext = "avi";
00226   dlg.file("File", ext, file);
00227 
00228   static vidl_ffmpeg_ostream_params params;
00229 
00230   vcl_vector<vcl_string> enc_choices(8);
00231   enc_choices[0] = "-- Default --";
00232   enc_choices[1] = "MPEG4";
00233   enc_choices[2] = "MS MPEG4 v2";
00234   enc_choices[3] = "MPEG2";
00235   enc_choices[4] = "DV";
00236   enc_choices[5] = "LJPEG";
00237   enc_choices[6] = "Raw Video";
00238   enc_choices[7] = "Huff YUV";
00239   int enc_choice = params.encoder_;
00240   dlg.choice("encoder", enc_choices, enc_choice);
00241 
00242   dlg.field("frame rate (fps)", params.frame_rate_);
00243   dlg.field("bit rate", params.bit_rate_);
00244 
00245   if (!dlg.ask())
00246     return NULL;
00247 
00248   params.encoder(vidl_ffmpeg_ostream_params::
00249                  encoder_type(enc_choice));
00250 
00251   vidl_ffmpeg_ostream* o_stream = new vidl_ffmpeg_ostream(file, params);
00252 
00253   if (!o_stream) {
00254     vgui_error_dialog("Failed to create ffmpeg output stream");
00255     delete o_stream;
00256     return NULL;
00257   }
00258   return o_stream;
00259 
00260 #else // VIDL_HAS_FFMPEG
00261   vgui_error_dialog("FFMPEG support not compiled in");
00262   return NULL;
00263 #endif // VIDL_HAS_FFMPEG
00264 }
00265 
00266 //-----------------------------------------------------------------------------
00267 //: Use vgui dialogs to open a v4l2 istream
00268 //-----------------------------------------------------------------------------
00269 vidl_v4l2_istream* vidl_gui_param_dialog::v4l2_istream()
00270 {
00271 #if VIDL_HAS_VIDEODEV2
00272   vidl_v4l2_devices& devs= vidl_v4l2_devices::all();  // simpler name
00273 
00274   // Select Device
00275   int device_id=0;
00276   if (devs.size()==0) {
00277     vgui_error_dialog("No video devices found");
00278     return NULL;
00279   }
00280   else if (devs.size() > 1) {
00281     vgui_dialog dlg("Select a video device");
00282     vcl_vector<vcl_string> video_names;
00283     for (unsigned int i=0; i<devs.size(); ++i) {
00284       vcl_stringstream ss;
00285       ss << devs(i).card_name()
00286          << " (" << devs(i).device_file() << ')';
00287       video_names.push_back(ss.str());
00288     }
00289     dlg.choice("Device",video_names,device_id);
00290     if (!dlg.ask())
00291       return NULL;
00292   }
00293   // Select Input
00294   int input_id=0;
00295   if (devs(device_id).n_inputs()>1) {
00296     vgui_dialog dlg("Select input");
00297     vcl_vector<vcl_string> input_names;
00298     for (unsigned int i=0; i<devs(device_id).n_inputs(); ++i) {
00299       input_names.push_back(devs(device_id).card_name()+"->"+
00300                             devs(device_id).input(i).name());
00301     }
00302     dlg.choice("Input",input_names,input_id);
00303     if (!dlg.ask())
00304       return NULL;
00305   }
00306   // Selecting input
00307   if (!devs(device_id).set_input(input_id))  {
00308     vgui_error_dialog("Input not set");
00309     return NULL;
00310   }
00311   // Has a valid format been detected?
00312   if (!devs(device_id).format_is_set())  {
00313     vgui_error_dialog("A valid format has not been detected");
00314     return NULL;
00315   }
00316   // Set width and height
00317   if (!devs(device_id).set_v4l2_format(
00318                                  devs(device_id).get_v4l2_format(),
00319                                  640,480)) { // could w,h be changed?
00320     vgui_error_dialog("Size 640x480 not possible");
00321     return NULL;
00322   }
00323   // checking if device is ok for capturing
00324   if (!devs(device_id)) {
00325     vgui_error_dialog(("Error in device: "+
00326                        devs(device_id).get_error()).c_str());
00327     return NULL;
00328   }
00329 
00330   vidl_v4l2_istream* i_stream = new vidl_v4l2_istream(devs(device_id));
00331   if (!i_stream->is_valid()) {
00332     vgui_error_dialog("Failed to create input stream");
00333     delete i_stream;
00334     return NULL;
00335   }
00336   return i_stream;
00337 #else // VIDL_HAS_VIDEODEV2
00338   vgui_error_dialog("v4l2 support not compiled in");
00339   return NULL;
00340 #endif // VIDL_HAS_VIDEODEV2
00341 }
00342 
00343 //-----------------------------------------------------------------------------
00344 //: Use vgui dialogs to open a dc1394 istream
00345 //-----------------------------------------------------------------------------
00346 vidl_dc1394_istream* vidl_gui_param_dialog::dc1394_istream()
00347 {
00348 #if VIDL_HAS_DC1394
00349   vgui_dialog dlg("Open dc1394 Input Stream");
00350 
00351   //: Probe cameras for valid options
00352   vidl_iidc1394_params::valid_options options;
00353   vidl_dc1394_istream::valid_params(options);
00354 
00355   if (options.cameras.empty()) {
00356     vgui_error_dialog("No cameras found");
00357     return NULL;
00358   }
00359 
00360 #ifndef NDEBUG
00361   vcl_cout << "Detected " << options.cameras.size() << " cameras\n";
00362   for (unsigned int i=0; i<options.cameras.size(); ++i) {
00363     const vidl_iidc1394_params::valid_options::camera& cam = options.cameras[i];
00364     vcl_cout << "Camera "<<i<<": "<< cam.vendor << " : " << cam.model
00365              << " : guid "<< vcl_hex << cam.guid << '\n';
00366     for (unsigned int j=0; j<cam.modes.size(); ++j) {
00367       const vidl_iidc1394_params::valid_options::valid_mode& m = cam.modes[j];
00368       vcl_cout << "\tmode "<<j<<" : "
00369                << vidl_iidc1394_params::video_mode_string(m.mode) << '\n';
00370       for (unsigned int k=0; k<m.frame_rates.size(); ++k) {
00371         vcl_cout << "\t\tframe rate : "
00372                  << vidl_iidc1394_params::frame_rate_val(m.frame_rates[k]) << '\n';
00373       }
00374     }
00375   }
00376   vcl_cout << vcl_endl;
00377 #endif
00378 
00379   vidl_iidc1394_params params;
00380 
00381   // Select the camera
00382   //-----------------------------------
00383   static unsigned int camera_id = 0;
00384   if (options.cameras.size() <= camera_id)
00385     camera_id = 0;
00386 
00387   if (options.cameras.size() > 1) {
00388     vgui_dialog dlg("Select an IIDC 1394 camera");
00389     vcl_vector<vcl_string> camera_names;
00390     for (unsigned int i=0; i<options.cameras.size(); ++i) {
00391       vcl_stringstream ss;
00392       ss << options.cameras[i].vendor << ' '
00393          << options.cameras[i].model
00394          << " (guid "<< vcl_hex << options.cameras[i].guid << ')';
00395       camera_names.push_back(ss.str());
00396     }
00397     dlg.choice("Camera",camera_names,camera_id);
00398     if (!dlg.ask())
00399       return NULL;
00400   }
00401   const vidl_iidc1394_params::valid_options::camera& cam = options.cameras[camera_id];
00402   params.guid_ = cam.guid;
00403 
00404   // Select the mode
00405   //-----------------------------------
00406   if (cam.modes.empty())
00407   {
00408     vgui_error_dialog("No valid modes for this camera");
00409     return NULL;
00410   }
00411   static unsigned int mode_id = 0;
00412   bool use_1394b = cam.b_mode;
00413   if (cam.modes.size() > 1) {
00414     vgui_dialog dlg("Select a capture mode");
00415     vcl_vector<vcl_string> mode_names;
00416     for (unsigned int i=0; i<cam.modes.size(); ++i) {
00417       if (cam.modes[i].mode ==  cam.curr_mode)
00418         mode_id = i;
00419       mode_names.push_back(vidl_iidc1394_params::video_mode_string(cam.modes[i].mode));
00420     }
00421     dlg.choice("Mode",mode_names,mode_id);
00422     dlg.checkbox("1394b",use_1394b);
00423     if (!dlg.ask())
00424       return NULL;
00425   }
00426   const vidl_iidc1394_params::valid_options::valid_mode& m = cam.modes[mode_id];
00427   params.video_mode_ = m.mode;
00428   params.b_mode_ = use_1394b;
00429   params.speed_ = use_1394b ? vidl_iidc1394_params::ISO_SPEED_800 : vidl_iidc1394_params::ISO_SPEED_400;
00430 
00431 
00432   // Select the frame rate
00433   //-----------------------------------
00434   if (vidl_iidc1394_params::video_format_val(m.mode) < 6) {
00435     if (m.frame_rates.empty())
00436     {
00437       vgui_error_dialog("No valid frame rates for this mode");
00438       return NULL;
00439     }
00440     static unsigned int fr_id = 0;
00441     if (m.frame_rates.size() > 1) {
00442       vgui_dialog dlg("Select a frame rate");
00443       vcl_vector<vcl_string> rate_names;
00444       for (unsigned int i=0; i<m.frame_rates.size(); ++i) {
00445         if (m.frame_rates[i] == cam.curr_frame_rate)
00446           fr_id = i;
00447         vcl_stringstream name;
00448         name << vidl_iidc1394_params::frame_rate_val(m.frame_rates[i]) << " fps";
00449         rate_names.push_back(name.str());
00450       }
00451       dlg.choice("Frame Rate",rate_names,fr_id);
00452       if (!dlg.ask())
00453         return NULL;
00454     }
00455     params.frame_rate_ = m.frame_rates[fr_id];
00456   }
00457 
00458   // Select the feature values
00459   //-------------------------------------
00460   if (!cam.features.empty()) {
00461     params.features_ = cam.features;
00462     if (!update_iidc1394_params(params.features_))
00463       return NULL;
00464   }
00465 
00466   static unsigned int num_dma_buffers = 3;
00467   static bool drop_frames = false;
00468   {
00469     vgui_dialog dlg("Enter DMA Options");
00470     dlg.field("Number of DMA Buffers",num_dma_buffers);
00471     dlg.checkbox("Drop Frames",drop_frames);
00472     if (!dlg.ask())
00473       return NULL;
00474   }
00475 
00476   vidl_dc1394_istream* i_stream = new vidl_dc1394_istream();
00477   i_stream->open(num_dma_buffers, drop_frames, params);
00478   if (!i_stream || !i_stream->is_open()) {
00479     vgui_error_dialog("Failed to open the input stream");
00480     delete i_stream;
00481     return NULL;
00482   }
00483   return i_stream;
00484 
00485 
00486 #else // VIDL_HAS_DC1394
00487   vgui_error_dialog("dc1394 support not compiled in");
00488   return NULL;
00489 #endif // VIDL_HAS_DC1394
00490 }
00491 
00492 
00493 //-----------------------------------------------------------------------------
00494 //: Use a vgui dialog to update iidc1394 camera parameters
00495 //-----------------------------------------------------------------------------
00496 bool vidl_gui_param_dialog::update_iidc1394_params(vcl_vector<vidl_iidc1394_params::
00497                                                    feature_options>& features)
00498 {
00499   vgui_dialog dlg("Set feature values");
00500   vcl_vector<unsigned> choices(features.size(),0);
00501   for (unsigned int i=0; i<features.size(); ++i) {
00502     vidl_iidc1394_params::feature_options& f = features[i];
00503     vcl_stringstream ss;
00504 
00505     vcl_vector<vcl_string> modes;
00506     for (unsigned int j=0; j<f.available_modes.size(); ++j) {
00507       modes.push_back(vidl_iidc1394_params::feature_mode_string(f.available_modes[j]));
00508       if (f.active_mode == f.available_modes[j])
00509         choices[i] = j;
00510     }
00511 
00512     ss << vidl_iidc1394_params::feature_string(f.id);
00513 
00514     if ( f.id == vidl_iidc1394_params::FEATURE_WHITE_BALANCE ) {
00515       if (modes.empty()) {
00516         dlg.message(ss.str().c_str());
00517         ss.str("");
00518         ss << "Blue Value (U) [" << f.min << " - "<<f.max<<"] : " << f.BU_value;
00519         dlg.message(ss.str().c_str());
00520         ss.str("");
00521         ss << " Red Value (V) [" << f.min << " - "<<f.max<<"] : " << f.RV_value;
00522         dlg.message(ss.str().c_str());
00523       }
00524       else {
00525         dlg.choice(ss.str().c_str(), modes, choices[i]);
00526 
00527         ss.str("");
00528         ss << "Blue Value (U) [" << f.min << " - "<<f.max<<']';
00529         dlg.field(ss.str().c_str(), f.BU_value);
00530 
00531         ss.str("");
00532         ss << " Red Value (V) [" << f.min << " - "<<f.max<<']';
00533         dlg.field(ss.str().c_str(), f.RV_value);
00534       }
00535     }
00536     else
00537     {
00538       if (modes.empty()) {
00539         dlg.message(ss.str().c_str());
00540         ss.str("");
00541         ss << "Value [" << f.min << " - "<<f.max<<"] : " << f.value;
00542         dlg.message(ss.str().c_str());
00543       }
00544       else
00545       {
00546         dlg.choice(ss.str().c_str(), modes, choices[i]);
00547 
00548         ss.str("");
00549         ss << "Value [" << f.min << " - "<<f.max<<']';
00550         dlg.field(ss.str().c_str(), f.value);
00551         if (f.absolute_capable) {
00552           ss.str("");
00553           ss << "Absolute Value [" << f.abs_min << " - "<<f.abs_max<<']';
00554           dlg.field(ss.str().c_str(), f.abs_value);
00555         }
00556       }
00557     }
00558   }
00559 
00560   if (!dlg.ask())
00561     return false;
00562 
00563   for (unsigned int i=0; i<features.size(); ++i) {
00564     vidl_iidc1394_params::feature_options& f = features[i];
00565     if (f.available_modes.empty())
00566       continue;
00567 
00568     vcl_vector<vidl_iidc1394_params::feature_mode_t> modes;
00569     for (unsigned int j=0; j<f.available_modes.size(); ++j) {
00570       modes.push_back(static_cast<vidl_iidc1394_params::feature_mode_t>
00571                       (f.available_modes[j]) );
00572     }
00573     f.active_mode = modes[choices[i]];
00574   }
00575   return true;
00576 }