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/videodev.h> 00025 #include <linux/videodev2.h> 00026 00027 TypeHandle WebcamVideoV4L::_type_handle; 00028 00029 //////////////////////////////////////////////////////////////////// 00030 // Function: find_all_webcams_v4l 00031 // Access: Public, Static 00032 // Description: Finds all Video4Linux webcams and adds them to 00033 // the global list _all_webcams. 00034 //////////////////////////////////////////////////////////////////// 00035 void find_all_webcams_v4l() { 00036 struct video_capability cap; 00037 struct v4l2_capability cap2; 00038 00039 vector_string devs; 00040 GlobPattern pattern ("/dev/video*"); 00041 pattern.match_files(devs); 00042 for (vector_string::iterator it = devs.begin(); it != devs.end(); ++it) { 00043 int fd = open(it->c_str(), O_RDWR); 00044 if (fd != -1) { 00045 // Check for Video4Linux2 capabilities 00046 if (ioctl(fd, VIDIOC_QUERYCAP, &cap2) != -1) { 00047 if ((cap2.capabilities & V4L2_CAP_VIDEO_CAPTURE) && 00048 (cap2.capabilities & V4L2_CAP_STREAMING)) { 00049 struct v4l2_fmtdesc fmt; 00050 for (int i = 0;; i++) { 00051 memset(&fmt, 0, sizeof fmt); 00052 fmt.index = i; 00053 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 00054 if (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == -1) { 00055 break; 00056 } 00057 struct v4l2_frmsizeenum frmsizeenum; 00058 for (int j = 0;; j++) { 00059 memset(&frmsizeenum, 0, sizeof frmsizeenum); 00060 frmsizeenum.index = j; 00061 frmsizeenum.pixel_format = fmt.pixelformat; 00062 if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == -1) { 00063 break; 00064 } 00065 if (frmsizeenum.type != V4L2_FRMSIZE_TYPE_DISCRETE) { 00066 continue; 00067 } 00068 struct v4l2_frmivalenum frmivalenum; 00069 for (int k = 0;; k++) { 00070 memset(&frmivalenum, 0, sizeof frmivalenum); 00071 frmivalenum.index = k; 00072 frmivalenum.pixel_format = fmt.pixelformat; 00073 frmivalenum.width = frmsizeenum.discrete.width; 00074 frmivalenum.height = frmsizeenum.discrete.height; 00075 if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmivalenum) == -1) { 00076 break; 00077 } 00078 if (frmivalenum.type != V4L2_FRMIVAL_TYPE_DISCRETE) { 00079 continue; 00080 } 00081 00082 // Create a new webcam video object 00083 PT(WebcamVideoV4L) wc = new WebcamVideoV4L; 00084 wc->set_name((const char*) cap2.card); 00085 wc->_device = *it; 00086 wc->_size_x = frmsizeenum.discrete.width; 00087 wc->_size_y = frmsizeenum.discrete.height; 00088 wc->_fps = ((double) frmivalenum.discrete.denominator) / ((double) frmivalenum.discrete.numerator); 00089 wc->_pformats.push_back(fmt.pixelformat); 00090 00091 // Iterate through the webcams to make sure we don't put any duplicates in there 00092 pvector<PT(WebcamVideo)>::iterator wvi; 00093 for (wvi = WebcamVideoV4L::_all_webcams.begin(); wvi != WebcamVideoV4L::_all_webcams.end(); ++wvi) { 00094 if ((*wvi)->is_of_type(WebcamVideoV4L::get_class_type())) { 00095 PT(WebcamVideoV4L) wv_v4l = DCAST(WebcamVideoV4L, *wvi); 00096 if (wv_v4l->_device == wc->_device && 00097 wv_v4l->_size_x == wc->_size_x && 00098 wv_v4l->_size_y == wc->_size_y && 00099 wv_v4l->_fps == wc->_fps) { 00100 wv_v4l->_pformats.push_back(fmt.pixelformat); 00101 break; 00102 } 00103 } 00104 } 00105 // Did the loop finish, meaning that a webcam of these 00106 // properties does not exist? Add it. 00107 if (wvi == WebcamVideoV4L::_all_webcams.end()) { 00108 WebcamVideoV4L::_all_webcams.push_back(DCAST(WebcamVideo, wc)); 00109 } 00110 } 00111 } 00112 } 00113 continue; 00114 } 00115 } 00116 00117 // Check for Video4Linux capabilities 00118 if (ioctl(fd, VIDIOCGCAP, &cap) != -1) { 00119 if (cap.type & VID_TYPE_CAPTURE) { 00120 //TODO: Video4Linux support 00121 continue; 00122 } 00123 } 00124 } 00125 close(fd); 00126 } 00127 } 00128 00129 //////////////////////////////////////////////////////////////////// 00130 // Function: WebcamVideoV4L::open 00131 // Access: Published, Virtual 00132 // Description: Open this video, returning a MovieVideoCursor. 00133 //////////////////////////////////////////////////////////////////// 00134 PT(MovieVideoCursor) WebcamVideoV4L:: 00135 open() { 00136 return new WebcamVideoCursorV4L(this); 00137 } 00138 00139 #endif