/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2012 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLIO/src/UnicapGrabber.cpp ** ** Module : ICLIO ** ** Authors: Christof Elbrechter, Robert Haschke ** ** ** ** ** ** Commercial License ** ** ICL can be used commercially, please refer to our website ** ** www.iclcv.org for more details. ** ** ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the ** ** GNU General Public License version 3.0 as published by the ** ** Free Software Foundation and appearing in the file LICENSE.GPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the GNU General Public License ** ** version 3.0 requirements will be met: ** ** http://www.gnu.org/copyleft/gpl.html. ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** *********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace icl; using namespace std; namespace icl{ UnicapGrabberImpl::UnicapGrabberImpl(const UnicapDevice &device): // {{{ open m_oDevice(device),m_poImage(0), m_poGrabEngine(0),m_poConvertEngine(0), m_bUseDMA(false), m_bProgressiveGrabMode(true){ init(); } // }}} UnicapGrabberImpl::UnicapGrabberImpl(const std::string &deviceFilter, unsigned int useIndex): // {{{ open m_poImage(0),m_poGrabEngine(0), m_poConvertEngine(0), m_bUseDMA(false), m_bProgressiveGrabMode(true){ const std::vector &ds = getUnicapDeviceList(deviceFilter); if(useIndex < ds.size()){ m_oDevice = ds[useIndex]; }else{ ERROR_LOG("no device found for filter: \""< uppers('A','Z'); static const int offs = 'A' - 'a'; string r=s; for(unsigned int i=0;i &v){ // {{{ open if(!v.size()) return "{}"; std::ostringstream os; os << '{'; for(unsigned int i=0;i ts = tok(value,"x"); if(ts.size() != 2){ ERROR_LOG("unable to set parameter size to \""< tmp = tok(value,"&"); if(tmp.size() != 2){ ERROR_LOG("unable to set parameter format&size to \""< ts = tok(size,"x"); if(ts.size() != 2){ ERROR_LOG("unable to set size of parameter format&size to \""< ps = m_oDevice.getProperties(); for(unsigned int i=0;i range = prop.getRange(); double val = atof(value.c_str()); if(range.contains(val)){ prop.setValue(val); m_oDevice.setProperty(prop); // if(verbose) printf("UnicapGrabberImpl::setParam(%s=%s) [done]\n",param.c_str(),value.c_str()); }else{ printf("UnicapGrabberImpl::setParam() value %f is out of range [%f..%f]\n",val,range.minVal, range.maxVal); } break; } // }}} case UnicapProperty::valueList:{ // {{{ open vector valueList = prop.getValueList(); double val = atof(value.c_str()); bool foundValue = false; for(unsigned int j=0;j men = prop.getMenu(); string val = force_lower_case(value); bool foundEntry = false; for(unsigned int j=0;j UnicapGrabberImpl::getPropertyList(){ // {{{ open vector v; v.push_back("size"); v.push_back("format"); // [deprecated !] v.push_back("size&format"); v.push_back("dma"); v.push_back("grab mode"); vector ps = m_oDevice.getProperties(); for(unsigned int i=0;i sizes = fmt.getPossibleSizes(); if(sizes.size()){ return sizeVecToStr(sizes); }else{ Size others[] = {fmt.getSize(),fmt.getMinSize(),fmt.getMaxSize()}; for(int i=0;i<3;i++){ if(others[i] != Size::null && others[i] != Size(-1,-1)){ return string("{\"")+str(others[i])+"\"}"; } } return "{}"; } // }}} }else if(name == "format"){ // {{{ open vector fmts = m_oDevice.getFormats(); if(!fmts.size()) return "{}"; string s = "{"; for(unsigned i = 0;i fmts = m_oDevice.getFormats(); for(unsigned i = 0;i sizes = fmts[i].getPossibleSizes(); if(sizes.size()){ for(unsigned int j=0;j ps = m_oDevice.getProperties(); bool found = false; for(unsigned int i=0;i r = p.getRange(); return Grabber::translateSteppingRange(SteppingRange(r.minVal,r.maxVal,p.getStepping())); }else if(t == "valueList"){ return Grabber::translateDoubleVec(p.getValueList()); }else{ return "undefined"; } } // }}} } // }}} string UnicapGrabberImpl::getType(const string &name){ // {{{ open static map *typeMap = 0; if(!typeMap){ typeMap = new map; (*typeMap)[UnicapProperty::valueList] = "valueList"; (*typeMap)[UnicapProperty::menu] = "menu"; (*typeMap)[UnicapProperty::range] = "range"; (*typeMap)[UnicapProperty::flags] = "undefined"; (*typeMap)[UnicapProperty::data] = "undefined"; (*typeMap)[UnicapProperty::anytype] = "undefined"; } vector ps = m_oDevice.getProperties(); for(unsigned int i=0;i ps = m_oDevice.getProperties(); for(unsigned int i=0;ilockGrabber(); if(m_poGrabEngine->needsConversion()){ const icl8u *rawData = m_poGrabEngine->getCurrentFrameUnconverted(); m_poConvertEngine->cvtNative(rawData,&m_poImage); }else{ ERROR_LOG("unable to estimate hardware image parameters!\n" "returning NULL"); return 0; } m_poGrabEngine->unlockGrabber(); m_oMutex.unlock(); updateFps(); return m_poImage; } // }}} namespace{ enum matchmode{ eq, // == equal in, // ~= contains rx // *= regex-match }; bool match_regex(const string &text,const string &patternIn){ // {{{ open string patternSave = patternIn; char *pattern = const_cast(patternSave.c_str()); int status; regex_t re; if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) { ERROR_LOG("error in regular expression " << patternIn); return false; } status = regexec(&re, text.c_str(), (size_t) 0, NULL, 0); regfree(&re); return !status; } // }}} bool match_string(const string &text, const string &pattern, matchmode mode){ switch(mode){ case eq: return text == pattern; case in: return text.find(pattern,0) != string::npos; default: return match_regex(text,pattern); } } struct ParamFilter{ // {{{ open ParamFilter(const string &str,matchmode mode, unsigned int ui=0, unsigned long long ull=0): str(str),ui(ui),ull(ull),mode(mode){ } virtual ~ParamFilter(){} virtual bool ok(const UnicapDevice &d)=0; string str; unsigned int ui; unsigned long long ull; matchmode mode; }; // }}} struct ParamFilterID : public ParamFilter{ // {{{ open ParamFilterID(const string &id, matchmode mode):ParamFilter(str,mode){} virtual bool ok(const UnicapDevice &d){ return match_string(d.getID(),str,mode); } }; // }}} struct ParamFilterModelName : public ParamFilter{ // {{{ open ParamFilterModelName(const string &mn, matchmode mode):ParamFilter(mn,mode){} virtual bool ok(const UnicapDevice &d){ return match_string(d.getModelName(),str,mode); } }; // }}} struct ParamFilterVendorName : public ParamFilter{ // {{{ open ParamFilterVendorName(const string &vn, matchmode mode):ParamFilter(vn,mode){} virtual bool ok(const UnicapDevice &d){ return match_string(d.getVendorName(),str,mode); } }; // }}} struct ParamFilterModelID : public ParamFilter{ // {{{ open ParamFilterModelID(unsigned long long mid, matchmode mode):ParamFilter("",mode,0,mid){} virtual bool ok(const UnicapDevice &d){ return d.getModelID()==ull; } }; // }}} struct ParamFilterVendorID : public ParamFilter{ // {{{ open ParamFilterVendorID(unsigned int vid, matchmode mode):ParamFilter("",mode,vid){} virtual bool ok(const UnicapDevice &d){ return d.getVendorID()==ui; } }; // }}} struct ParamFilterCPILayer : public ParamFilter{ // {{{ open ParamFilterCPILayer(const string &cpil, matchmode mode):ParamFilter(cpil,mode){} virtual bool ok(const UnicapDevice &d){ return match_string(d.getCPILayer(),str,mode); } }; // }}} struct ParamFilterDevice : public ParamFilter{ // {{{ open ParamFilterDevice(const string &dev, matchmode mode):ParamFilter(dev,mode){} virtual bool ok(const UnicapDevice &d){ return match_string(d.getDevice(),str,mode); } }; // }}} struct ParamFilterFlags : public ParamFilter{ // {{{ open ParamFilterFlags(unsigned int flags, matchmode mode):ParamFilter("",mode,flags){} virtual bool ok(const UnicapDevice &d){ return d.getFlags()==ui; } }; // }}} void filter_devices(const vector &src, vector &dst, const string &filter){ // {{{ open dst.clear(); const std::vector toks = tok(filter,"\n"); vector filters; for(unsigned int i=0;iok(src[i])){ ok = false; break; } } if(ok) dst.push_back(src[i]); } for(unsigned int j=0;j UnicapGrabberImpl::getUnicapDeviceList(const string &filter){ // {{{ open static std::vector vCurrentDevices; // rebuild current list of available devices vCurrentDevices.clear(); for(int i=0;true;++i){ UnicapDevice d(i); if(!d.isValid()) break; vCurrentDevices.push_back(d); } return filterDevices (vCurrentDevices, filter); } // }}} /* Returning a real vector instead of a const reference to some static variable here allows to apply several filterDevices-calls in series */ vector UnicapGrabberImpl::filterDevices(const std::vector &devices, const string &filter){ // {{{ open std::vector vResult; filter_devices(devices,vResult,filter); return vResult; } // }}} } // {{{ unicap_device_t /************************************ typedef struct { char identifier [128]; char model_name [128] ; char vendor_name [128] ; unsigned long long model_id ; unsigned int vendor_id ; char cpi_layer [1024] ; char device [1024] ; unsigned int flags ; }unicap_device_t; *************************************/ // }}} // {{{ unicap_format_t /************************************ typedef struct{ char identifier[128]; // default unicap_rect_t size; // min and max extends unicap_rect_t min_size; unicap_rect_t max_size; // stepping: // 0 if no free scaling available int h_stepping; int v_stepping; // array of possible sizes unicap_rect_t *sizes; int size_count; int bpp; unsigned int fourcc; unsigned int flags; unsigned int buffer_types; // available buffer types int system_buffer_count; size_t buffer_size; unicap_buffer_type_t buffer_type; }; *************************************/ // }}} // {{{ unicap_property_t /************************************************************ struct unicap_property_t{ char identifier[128]; //mandatory char category[128]; char unit[128]; // // list of properties identifier which value / behaviour may change if this property changes char **relations; int relations_count; union { double value; // default if enumerated char menu_item[128]; }; union { unicap_property_range_t range; // if UNICAP_USE_RANGE is asserted unicap_property_value_list_t value_list; // if UNICAP_USE_VALUE_LIST is asserted unicap_property_menu_t menu; }; double stepping; unicap_property_type_enum_t type; u_int64_t flags; // defaults if enumerated u_int64_t flags_mask; // defines capabilities if enumerated // optional data void *property_data; size_t property_data_size; }; *********************************************************************/ // }}}