usb_cam_python.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. #include "usb_cam_python.h"
  2. #include <vector>
  3. #include <iostream>
  4. #include <thread>
  5. #include <mutex>
  6. #include <condition_variable>
  7. namespace iv {
  8. struct threadcam
  9. {
  10. std::thread * mpthread;
  11. std::string mstrvideoname;
  12. std::shared_ptr<char> mpstr_data;
  13. int mndatasize;
  14. std::mutex mmutexdata;
  15. usb_cam::UsbCam * mpusbcam;
  16. bool mbRun;
  17. bool mbUpdate;
  18. std::condition_variable mcv;
  19. std::mutex mmutexcv;
  20. };
  21. }
  22. std::vector<iv::threadcam * > gvectorthreadcam;
  23. std::mutex gmutex;
  24. using namespace usb_cam;
  25. bool gstreaming_status_;
  26. int gimage_width_, gimage_height_, gframerate_, gexposure_, gbrightness_, gcontrast_, gsaturation_, gsharpness_, gfocus_,
  27. gwhite_balance_, ggain_;
  28. bool gautofocus_, gautoexposure_, gauto_white_balance_;
  29. void setdefaultcvalue()
  30. {
  31. gbrightness_ = -1;// xp.GetParam("brightness", -1); //0-255, -1 "leave alone"
  32. gcontrast_ = -1;//xp.GetParam("contrast", -1); //0-255, -1 "leave alone"
  33. gsaturation_ = -1;//xp.GetParam("saturation", -1); //0-255, -1 "leave alone"
  34. gsharpness_ = -1;//xp.GetParam("sharpness", -1); //0-255, -1 "leave alone"
  35. // possible values: mmap, read, userptr
  36. // gio_method_name_ = xp.GetParam("io_method", std::string("mmap"));
  37. // gimage_width_ = xp.GetParam("image_width", 1920);
  38. // gimage_height_ = xp.GetParam("image_height", 1080);
  39. // gframerate_ = xp.GetParam("framerate", 30);
  40. // possible values: yuyv, uyvy, mjpeg, yuvmono10, rgb24
  41. // gpixel_format_name_ = xp.GetParam("pixel_format", std::string("mjpeg"));
  42. // enable/disable autofocus
  43. gautofocus_ = false;//xp.GetParam("autofocus", false);
  44. gfocus_ = -1;//xp.GetParam("focus", -1); //0-255, -1 "leave alone"
  45. // enable/disable autoexposure
  46. gautoexposure_ = true;//xp.GetParam("autoexposure", true);
  47. gexposure_ = 100;//xp.GetParam("exposure", 100);
  48. ggain_ = -1;//xp.GetParam("gain", -1); //0-100?, -1 "leave alone"
  49. // enable/disable auto white balance temperature
  50. gauto_white_balance_ = true;//xp.GetParam("auto_white_balance", true);
  51. gwhite_balance_ = 4000;//xp.GetParam("white_balance", 4000);
  52. // load the camera info
  53. // xp.GetParam("camera_frame_id", img_.header.frame_id, std::string("head_camera"));
  54. // gcamera_name_ = "head_camera";// xp.GetParam("camera_name", std::string("head_camera"));
  55. // gcamera_info_url_ = "";//xp.GetParam("camera_info_url", std::string(""));
  56. }
  57. void threadcam(iv::threadcam * pthreadcam)
  58. {
  59. while(pthreadcam->mbRun)
  60. {
  61. std::shared_ptr<char> mpstr_buf = std::shared_ptr<char>(new char[1000000]);
  62. int nLen = 0;
  63. // std::cout<< "grab."<<std::endl;
  64. pthreadcam->mpusbcam->grab_image(mpstr_buf.get(),&nLen,1000000);
  65. if(nLen> 0)
  66. {
  67. pthreadcam->mmutexdata.lock();
  68. pthreadcam->mndatasize = nLen;
  69. pthreadcam->mpstr_data = mpstr_buf;
  70. pthreadcam->mbUpdate = true;
  71. pthreadcam->mmutexdata.unlock();
  72. pthreadcam->mcv.notify_all();
  73. // std::cout<<std::chrono::system_clock::now().time_since_epoch().count()/1000<< " "<<nLen<<std::endl;
  74. }
  75. else
  76. {
  77. std::cout<<std::chrono::system_clock::now().time_since_epoch().count()/1000000<<" read camera "<<pthreadcam->mstrvideoname<<" fail."<<std::endl;
  78. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  79. }
  80. }
  81. pthreadcam->mpusbcam->stop_capturing();
  82. pthreadcam->mpusbcam->shutdown();
  83. delete pthreadcam->mpusbcam;
  84. }
  85. extern "C"
  86. {
  87. int StartCam(const char * strvideoname,int image_width,int image_height,int image_framerate)
  88. {
  89. usb_cam::UsbCam * pcamx = new usb_cam::UsbCam;
  90. // set the IO method
  91. UsbCam::io_method io_method = UsbCam::io_method_from_string("mmap");
  92. if(io_method == UsbCam::IO_METHOD_UNKNOWN)
  93. {
  94. std::cout<<"Unknown IO method mmap "<<std::endl;
  95. return 0;
  96. }
  97. // set the pixel format
  98. UsbCam::pixel_format pixel_format = UsbCam::pixel_format_from_string("mjpeg");
  99. if (pixel_format == UsbCam::PIXEL_FORMAT_UNKNOWN)
  100. {
  101. std::cout<<" Unknown pixel format mjpeg"<<std::endl;
  102. return 0;
  103. }
  104. // std::cout<<"hear."<<std::endl;
  105. std::cout<<"video name "<<strvideoname<<std::endl;
  106. // start the camera
  107. pcamx->start(strvideoname, io_method, pixel_format, image_width,
  108. image_height, image_framerate);
  109. setdefaultcvalue();
  110. // set camera parameters
  111. if (gbrightness_ >= 0)
  112. {
  113. pcamx->set_v4l_parameter("brightness", gbrightness_);
  114. }
  115. if (gcontrast_ >= 0)
  116. {
  117. pcamx->set_v4l_parameter("contrast", gcontrast_);
  118. }
  119. if (gsaturation_ >= 0)
  120. {
  121. pcamx->set_v4l_parameter("saturation", gsaturation_);
  122. }
  123. if (gsharpness_ >= 0)
  124. {
  125. pcamx->set_v4l_parameter("sharpness", gsharpness_);
  126. }
  127. if (ggain_ >= 0)
  128. {
  129. pcamx->set_v4l_parameter("gain", ggain_);
  130. }
  131. // check auto white balance
  132. if (gauto_white_balance_)
  133. {
  134. pcamx->set_v4l_parameter("white_balance_temperature_auto", 1);
  135. }
  136. else
  137. {
  138. pcamx->set_v4l_parameter("white_balance_temperature_auto", 0);
  139. pcamx->set_v4l_parameter("white_balance_temperature", gwhite_balance_);
  140. }
  141. // check auto exposure
  142. if (!gautoexposure_)
  143. {
  144. // turn down exposure control (from max of 3)
  145. pcamx->set_v4l_parameter("exposure_auto", 1);
  146. // change the exposure level
  147. pcamx->set_v4l_parameter("exposure_absolute", gexposure_);
  148. }
  149. // check auto focus
  150. if (gautofocus_)
  151. {
  152. pcamx->set_auto_focus(1);
  153. pcamx->set_v4l_parameter("focus_auto", 1);
  154. }
  155. else
  156. {
  157. pcamx->set_v4l_parameter("focus_auto", 0);
  158. if (gfocus_ >= 0)
  159. {
  160. pcamx->set_v4l_parameter("focus_absolute", gfocus_);
  161. }
  162. }
  163. pcamx->set_useRawMJPEG(true);
  164. iv::threadcam * xthreadcam = new iv::threadcam;
  165. xthreadcam->mbRun = true;
  166. xthreadcam->mbUpdate = false;
  167. xthreadcam->mpusbcam = pcamx;
  168. xthreadcam->mstrvideoname = strvideoname;
  169. xthreadcam->mpthread = new std::thread(threadcam,xthreadcam);
  170. gvectorthreadcam.push_back(xthreadcam);
  171. return 1;
  172. }
  173. int GetJPEGDataWithWait(char * strvideoname, char * str,int * x,int nwaitms)
  174. {
  175. std::string strvideo = strvideoname;
  176. int nsize = gvectorthreadcam.size();
  177. int i;
  178. iv::threadcam * pthreadcam = NULL;
  179. for(i=0;i<nsize;i++)
  180. {
  181. if(gvectorthreadcam[i]->mstrvideoname == strvideo)
  182. {
  183. pthreadcam = gvectorthreadcam[i];
  184. break;
  185. }
  186. }
  187. if(pthreadcam == NULL)
  188. {
  189. std::cout<<" video device not open."<<std::endl;
  190. return 0;
  191. }
  192. int nRtn = 0;
  193. pthreadcam->mmutexdata.lock();
  194. if(pthreadcam->mbUpdate)
  195. {
  196. // str.copy(gstrbuf,gnLen);
  197. memcpy(str,pthreadcam->mpstr_data.get(),pthreadcam->mndatasize);
  198. nRtn = pthreadcam->mndatasize;
  199. *x = pthreadcam->mndatasize;
  200. pthreadcam->mbUpdate= false;
  201. }
  202. pthreadcam->mmutexdata.unlock();
  203. if(nRtn > 0)return nRtn;
  204. if(nwaitms == 0)return nRtn;
  205. std::unique_lock<std::mutex> lk(pthreadcam->mmutexcv);
  206. if(pthreadcam->mcv.wait_for(lk,std::chrono::milliseconds(nwaitms)) == std::cv_status::timeout)
  207. {
  208. lk.unlock();
  209. }
  210. else
  211. {
  212. lk.unlock();
  213. }
  214. pthreadcam->mmutexdata.lock();
  215. if(pthreadcam->mbUpdate)
  216. {
  217. // str.copy(gstrbuf,gnLen);
  218. memcpy(str,pthreadcam->mpstr_data.get(),pthreadcam->mndatasize);
  219. nRtn = pthreadcam->mndatasize;
  220. *x = pthreadcam->mndatasize;
  221. pthreadcam->mbUpdate= false;
  222. }
  223. pthreadcam->mmutexdata.unlock();
  224. return nRtn;
  225. }
  226. int GetJPEGData(char * strvideoname, char * str,int * x)
  227. {
  228. return GetJPEGDataWithWait(strvideoname,str,x,0);
  229. }
  230. int StopCam(char * strvideoname)
  231. {
  232. std::string strvideo = strvideoname;
  233. int nsize =gvectorthreadcam.size();
  234. int i;
  235. iv::threadcam * pthreadcam = NULL;
  236. int index;
  237. gmutex.lock();
  238. for(i=0;i<nsize;i++)
  239. {
  240. if(gvectorthreadcam[i]->mstrvideoname == strvideo)
  241. {
  242. pthreadcam = gvectorthreadcam[i];
  243. index = i;
  244. break;
  245. }
  246. }
  247. if(pthreadcam == NULL)
  248. {
  249. std::cout<<" video device not open."<<std::endl;
  250. gmutex.unlock();
  251. return 0;
  252. }
  253. pthreadcam->mbRun = false;
  254. pthreadcam->mpthread->join();
  255. gvectorthreadcam.erase(gvectorthreadcam.begin() + index);
  256. gmutex.unlock();
  257. }
  258. }