00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00030
00031
00032
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
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
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
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
00104
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
00121
00122
00123
00124 PT(MovieVideoCursor) WebcamVideoV4L::
00125 open() {
00126 return new WebcamVideoCursorV4L(this);
00127 }
00128
00129 #endif