Panda3D
|
00001 // Filename: webcamVideoV4L.cxx 00002 // Created by: rdb (11Jun2010) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "webcamVideoV4L.h" 00016 00017 #ifdef HAVE_VIDEO4LINUX 00018 00019 #include "webcamVideoCursorV4L.h" 00020 #include "dcast.h" 00021 00022 #include <fcntl.h> 00023 #include <sys/ioctl.h> 00024 #include <linux/videodev2.h> 00025 00026 TypeHandle WebcamVideoV4L::_type_handle; 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: find_all_webcams_v4l 00030 // Access: Public, Static 00031 // Description: Finds all Video4Linux webcams and adds them to 00032 // the global list _all_webcams. 00033 //////////////////////////////////////////////////////////////////// 00034 void find_all_webcams_v4l() { 00035 struct v4l2_capability cap2; 00036 00037 vector_string devs; 00038 GlobPattern pattern ("/dev/video*"); 00039 pattern.match_files(devs); 00040 for (vector_string::iterator it = devs.begin(); it != devs.end(); ++it) { 00041 int fd = open(it->c_str(), O_RDWR); 00042 if (fd != -1) { 00043 // Check for Video4Linux2 capabilities 00044 if (ioctl(fd, VIDIOC_QUERYCAP, &cap2) != -1) { 00045 if ((cap2.capabilities & V4L2_CAP_VIDEO_CAPTURE) && 00046 (cap2.capabilities & V4L2_CAP_STREAMING)) { 00047 struct v4l2_fmtdesc fmt; 00048 for (int i = 0;; i++) { 00049 memset(&fmt, 0, sizeof fmt); 00050 fmt.index = i; 00051 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00052 if (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == -1) { 00053 break; 00054 } 00055 struct v4l2_frmsizeenum frmsizeenum; 00056 for (int j = 0;; j++) { 00057 memset(&frmsizeenum, 0, sizeof frmsizeenum); 00058 frmsizeenum.index = j; 00059 frmsizeenum.pixel_format = fmt.pixelformat; 00060 if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == -1) { 00061 break; 00062 } 00063 if (frmsizeenum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { 00064 continue; 00065 } 00066 struct v4l2_frmivalenum frmivalenum; 00067 for (int k = 0;; k++) { 00068 memset(&frmivalenum, 0, sizeof frmivalenum); 00069 frmivalenum.index = k; 00070 frmivalenum.pixel_format = fmt.pixelformat; 00071 frmivalenum.width = frmsizeenum.discrete.width; 00072 frmivalenum.height = frmsizeenum.discrete.height; 00073 if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmivalenum) == -1) { 00074 break; 00075 } 00076 if (frmivalenum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { 00077 continue; 00078 } 00079 00080 // Create a new webcam video object 00081 PT(WebcamVideoV4L) wc = new WebcamVideoV4L; 00082 wc->set_name((const char*) cap2.card); 00083 wc->_device = *it; 00084 wc->_size_x = frmsizeenum.discrete.width; 00085 wc->_size_y = frmsizeenum.discrete.height; 00086 wc->_fps = ((double) frmivalenum.discrete.denominator) / ((double) frmivalenum.discrete.numerator); 00087 wc->_pformats.push_back(fmt.pixelformat); 00088 00089 // Iterate through the webcams to make sure we don't put any duplicates in there 00090 pvector<PT(WebcamVideo)>::iterator wvi; 00091 for (wvi = WebcamVideoV4L::_all_webcams.begin(); wvi != WebcamVideoV4L::_all_webcams.end(); ++wvi) { 00092 if ((*wvi)->is_of_type(WebcamVideoV4L::get_class_type())) { 00093 PT(WebcamVideoV4L) wv_v4l = DCAST(WebcamVideoV4L, *wvi); 00094 if (wv_v4l->_device == wc->_device && 00095 wv_v4l->_size_x == wc->_size_x && 00096 wv_v4l->_size_y == wc->_size_y && 00097 wv_v4l->_fps == wc->_fps) { 00098 wv_v4l->_pformats.push_back(fmt.pixelformat); 00099 break; 00100 } 00101 } 00102 } 00103 // Did the loop finish, meaning that a webcam of these 00104 // properties does not exist? Add it. 00105 if (wvi == WebcamVideoV4L::_all_webcams.end()) { 00106 WebcamVideoV4L::_all_webcams.push_back(DCAST(WebcamVideo, wc)); 00107 } 00108 } 00109 } 00110 } 00111 continue; 00112 } 00113 } 00114 } 00115 close(fd); 00116 } 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: WebcamVideoV4L::open 00121 // Access: Published, Virtual 00122 // Description: Open this video, returning a MovieVideoCursor. 00123 //////////////////////////////////////////////////////////////////// 00124 PT(MovieVideoCursor) WebcamVideoV4L:: 00125 open() { 00126 return new WebcamVideoCursorV4L(this); 00127 } 00128 00129 #endif