static PyObject *Video_device_read_internal(Video_device *self, int queue) { if(!self->buffers) { ASSERT_OPEN; PyErr_SetString(PyExc_ValueError, "Buffers have not been created"); return NULL; } struct v4l2_buffer buffer; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(self->fd, VIDIOC_DQBUF, &buffer)) { return NULL; } PyObject *result = PyString_FromStringAndSize( self->buffers[buffer.index].start, buffer.bytesused); if(!result) { return NULL; } if(queue && my_ioctl(self->fd, VIDIOC_QBUF, &buffer)) { return NULL; } return result; }
static PyObject *Video_device_set_format(Video_device *self, PyObject *args) { int size_x; int size_y; int yuv420 = 0; if(!PyArg_ParseTuple(args, "ii|i", &size_x, &size_y, &yuv420)) { return NULL; } struct v4l2_format format; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = size_x; format.fmt.pix.height = size_y; #ifdef USE_LIBV4L format.fmt.pix.pixelformat = yuv420 ? V4L2_PIX_FMT_YUV420 : V4L2_PIX_FMT_RGB24; #else format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; #endif format.fmt.pix.field = V4L2_FIELD_INTERLACED; format.fmt.pix.bytesperline = 0; if(my_ioctl(self->fd, VIDIOC_S_FMT, &format)) { return NULL; } return Py_BuildValue("ii", format.fmt.pix.width, format.fmt.pix.height); }
static PyObject *Video_device_queue_all_buffers(Video_device *self) { if(!self->buffers) { ASSERT_OPEN; PyErr_SetString(PyExc_ValueError, "Buffers have not been created"); return NULL; } int i; int buffer_count = self->buffer_count; for(i = 0; i < buffer_count; i++) { struct v4l2_buffer buffer; buffer.index = i; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(self->fd, VIDIOC_QBUF, &buffer)) { return NULL; } } Py_RETURN_NONE; }
static PyObject *Video_device_stop(Video_device *self) { ASSERT_OPEN; enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(my_ioctl(self->fd, VIDIOC_STREAMOFF, &type)) { return NULL; } Py_RETURN_NONE; }
static PyObject *Video_device_set_fps(Video_device *self, PyObject *args) { int fps; if(!PyArg_ParseTuple(args, "i", &fps)) { return NULL; } struct v4l2_streamparm setfps; memset(&setfps, 0, sizeof(struct v4l2_streamparm)); setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; setfps.parm.capture.timeperframe.numerator = 1; setfps.parm.capture.timeperframe.denominator = fps; if(my_ioctl(self->fd, VIDIOC_S_PARM, &setfps)){ return NULL; } return Py_BuildValue("i",setfps.parm.capture.timeperframe.denominator); }
static void enumerate_menu (int fd, struct v4l2_queryctrl &queryctrl) { struct v4l2_querymenu querymenu; std::cout << " Menu items:" << std::endl; memset (&querymenu, 0, sizeof (querymenu)); querymenu.id = queryctrl.id; for (querymenu.index = queryctrl.minimum; querymenu.index <= queryctrl.maximum; querymenu.index++) { if (0 == my_ioctl (fd, VIDIOC_QUERYMENU, &querymenu)) { std::cout << " " << querymenu.index << " " << querymenu.name << std::endl; } else { std::cout << " Error VIDIOC_QUERYMENU" << std::endl; } } }
void Video_in_Manager::StopDeviceInternal() { if(verbose) printf("StopDeviceInternal\n"); if(this->fd==-1) { throw std::runtime_error("Device not started"); } //Signal V4l2 api enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(my_ioctl(this->fd, VIDIOC_STREAMOFF, &type)) { throw std::runtime_error("VIDIOC_STREAMOFF failed"); } this->deviceStarted = 0; }
int Video_in_Manager::GetFormatInternal() { struct v4l2_format format; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(my_ioctl(this->fd, VIDIOC_G_FMT, &format)) { return 0; } this->frameWidth = format.fmt.pix.width; this->frameHeight = format.fmt.pix.height; switch(format.fmt.pix.pixelformat) { case V4L2_PIX_FMT_MJPEG: this->pxFmt = "MJPEG"; break; case V4L2_PIX_FMT_RGB24: this->pxFmt = "RGB24"; break; case V4L2_PIX_FMT_YUV420: this->pxFmt = "YUV420"; break; case V4L2_PIX_FMT_YVU420: this->pxFmt = "YVU420"; break; case V4L2_PIX_FMT_YUYV: this->pxFmt = "YUYV"; break; default: this->pxFmt = "Unknown "; std::ostringstream oss; oss << format.fmt.pix.pixelformat; this->pxFmt.append(oss.str()); break; } if(verbose) printf("Current format %s %i %i\n", this->pxFmt.c_str(), this->frameWidth, this->frameHeight); return 1; }
static PyObject *Video_device_get_info(Video_device *self) { ASSERT_OPEN; struct v4l2_capability caps; if(my_ioctl(self->fd, VIDIOC_QUERYCAP, &caps)) { return NULL; } PyObject *set = PySet_New(NULL); if(!set) { return NULL; } struct capability *capability = capabilities; while((void *)capability < (void *)capabilities + sizeof(capabilities)) { if(caps.capabilities & capability->id) { PyObject *s = PyString_FromString(capability->name); if(!s) { Py_DECREF(set); return NULL; } PySet_Add(set, s); } capability++; } return Py_BuildValue("sssO", caps.driver, caps.card, caps.bus_info, set); }
int Video_in_Manager::SetFormatInternal(class SetFormatParams &args) { if(verbose) printf("SetFormatInternal\n"); //int size_x, int size_y, const char *fmt; struct v4l2_format format; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = args.width; format.fmt.pix.height = args.height; format.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; if(strcmp(args.fmt.c_str(), "MJPEG")==0) format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; if(strcmp(args.fmt.c_str(), "RGB24")==0) format.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; if(strcmp(args.fmt.c_str(), "YUV420")==0) format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; if(strcmp(args.fmt.c_str(), "YVU420")==0) format.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; if(strcmp(args.fmt.c_str(), "YUYV")==0) format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; format.fmt.pix.field = V4L2_FIELD_NONE; format.fmt.pix.bytesperline = 0; if(my_ioctl(this->fd, VIDIOC_S_FMT, &format)) { return 0; } //Store pixel format for decoding usage later //this->pxFmt = args.fmt; //this->frameWidth = args.width; //this->frameHeight = args.height; this->GetFormatInternal(); return 1; }
static PyObject *Video_device_set_format(Video_device *self, PyObject *args) { int size_x; int size_y; if(!PyArg_ParseTuple(args, "ii", &size_x, &size_y)) { return NULL; } struct v4l2_format format; format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = size_x; format.fmt.pix.height = size_y; format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; format.fmt.pix.field = V4L2_FIELD_NONE; format.fmt.pix.bytesperline = 0; if(my_ioctl(self->fd, VIDIOC_S_FMT, &format)) { return NULL; } return Py_BuildValue("ii", format.fmt.pix.width, format.fmt.pix.height); }
int main(int argc, char** argv) { if(argc == 2) { strcpy(my_video_dev, argv[1]); } else { strcpy(my_video_dev, "/dev/video0"); } //if (-1 == (fd = open(my_video_dev, O_RDWR))) { if (-1 == (fd = v4l1_open(my_video_dev, O_RDWR))) { printf("Error opening device: %s\n", my_video_dev); goto error; } //if( -1 == ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) ) { if( ioctl(fd, VIDIOC_QUERYCAP, &v4l2_capability) < 0 ) { printf("asd 1\n"); if( -1 == ioctl(fd, VIDIOCGCAP, &capability) ) { printf("asd 2\n"); printf("Error1: ioctl(fd,VIDIOCGCAP,&capability)\n"); camDriver = DRIVER_NONE; goto error; } else { printf("asd 3\n"); camDriver = DRIVER_V4L; } } else { printf("asd 4\n"); camDriver = DRIVER_V4L2; v4l1_close(fd); fd = v4l1_open(my_video_dev, O_RDWR); if( -1 == my_ioctl(VIDIOCGCAP, &capability)) { printf("asd 5\n"); printf("Error2: ioctl(fd,VIDIOCGCAP,&capability)\n"); goto error; } } // if( DRIVER_V4L == camDriver ) { printf("\n -----[ VIDIOCGCAP returns ]-----\n"); printf(" name: %s\n", capability.name); printf(" type: %i\n", capability.type); printf(" channels: %i\n", capability.channels); printf(" audios: %i\n", capability.audios); printf(" maxwidth: %i\n", capability.maxwidth); printf(" maxheight: %i\n", capability.maxheight); printf(" minwidth: %i\n", capability.minwidth); printf(" minheight: %i\n", capability.minheight); // } if (-1 == my_ioctl(VIDIOCGPICT,&picture)) { printf("Error: ioctl(fd,VIDIOCGCPICT,&picture)\n"); goto error; } printf("\n -----[ VIDIOCGPICT returns ]-----\n"); printf(" brightness: %i\n", picture.brightness); printf(" hue: %i\n", picture.hue); printf(" colour: %i\n", picture.colour); printf(" contrast: %i\n", picture.contrast); printf(" whiteness: %i\n", picture.whiteness); printf(" depth: %i\n", picture.depth); char static palet_tipi_str[64]; palette_name(palet_tipi_str, picture.palette); printf(" palette: %s\n\n", palet_tipi_str); vch.channel = 0; // vch.norm = VIDEO_MODE_PAL; if(-1 == my_ioctl(VIDIOCSCHAN,&vch)) { perror("Setting channel\n"); goto error; } fcntl(fd,F_SETFD,FD_CLOEXEC); if (-1 == my_ioctl(VIDIOCGMBUF,&gb_buffers)) { printf("Error: Error getting buffers\n"); goto error; } map = my_mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (map == NULL) { printf("Error: Mmap returned NULL\n"); goto error; } // Set up out capture to use the correct resolution my_buf.width = mywidth; my_buf.height = myheight; my_buf.format = VIDEO_PALETTE_RGB24; // Set up out video output SDL_Init(SDL_INIT_VIDEO); screen = SDL_SetVideoMode(mywidth, myheight, 24, SDL_SWSURFACE); if ( screen == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError()); exit(1); } SDL_WM_SetCaption("Oy oy oy teve pirogrami", NULL); // Tell the capture card to fill frame 0 my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" ilk my_buf.frame=0 da hata olustu\n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } // This is the infinate loop // We basically: // capture frame 1 // sync frame 0 // process frame 0 // capture frame 0 // sync frame 1 // process frame 1 // For more information, read the programming how-to that came with xawtv do { my_buf.frame = 1; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=1 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map); my_buf.frame = 0; if (-1 == my_ioctl(VIDIOCMCAPTURE, &my_buf)) { printf(" loop icinde frame=0 \n"); // printf("Error: Grabber chip can't sync (no station tuned in?)\n"); goto error; } my_buf.frame = 1; if (-1 == my_ioctl(VIDIOCSYNC, &my_buf.frame)) { printf("Error on sync!\n"); goto error; } copytoscreen(map + gb_buffers.offsets[1]); SDL_PollEvent(&event); } while (event.type != SDL_KEYDOWN); error: SDL_Quit(); return EXIT_SUCCESS; }
struct ifi_info * get_ifi_info(int family, int doaliases) { struct ifi_info *ifi, *ifihead, **ifipnext; int sockfd, len, lastlen, flags, myflags, idx = 0, hlen = 0; char *ptr, *buf, lastname[IFNAMSIZ], *cptr, *haddr, *sdlname; struct ifconf ifc; struct ifreq *ifr, ifrcopy; struct sockaddr_in *sinptr; struct sockaddr_in6 *sin6ptr; sockfd = my_socket(AF_INET, SOCK_DGRAM, 0); lastlen = 0; len = 100 * sizeof(struct ifreq); /* initial buffer size guess */ for ( ; ; ) { buf = my_malloc(len); ifc.ifc_len = len; ifc.ifc_buf = buf; if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) { if (errno != EINVAL || lastlen != 0) err_sys("ioctl error"); } else { if (ifc.ifc_len == lastlen) break; /* success, len has not changed */ lastlen = ifc.ifc_len; } len += 10 * sizeof(struct ifreq); /* increment */ free(buf); } ifihead = NULL; ifipnext = &ifihead; lastname[0] = 0; sdlname = NULL; /* end get_ifi_info1 */ /* include get_ifi_info2 */ for (ptr = buf; ptr < buf + ifc.ifc_len; ) { ifr = (struct ifreq *) ptr; #ifdef HAVE_SOCKADDR_SA_LEN len = max(sizeof(struct sockaddr), ifr->ifr_addr.sa_len); #else switch (ifr->ifr_addr.sa_family) { #ifdef IPV6 case AF_INET6: len = sizeof(struct sockaddr_in6); break; #endif case AF_INET: default: len = sizeof(struct sockaddr); break; } #endif /* HAVE_SOCKADDR_SA_LEN */ ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */ #ifdef HAVE_SOCKADDR_DL_STRUCT /* assumes that AF_LINK precedes AF_INET or AF_INET6 */ if (ifr->ifr_addr.sa_family == AF_LINK) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr; sdlname = ifr->ifr_name; idx = sdl->sdl_index; haddr = sdl->sdl_data + sdl->sdl_nlen; hlen = sdl->sdl_alen; } #endif if (ifr->ifr_addr.sa_family != family) continue; /* ignore if not desired address family */ myflags = 0; if ( (cptr = strchr(ifr->ifr_name, ':')) != NULL) *cptr = 0; /* replace colon with null */ if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0) { if (doaliases == 0) continue; /* already processed this interface */ myflags = IFI_ALIAS; } memcpy(lastname, ifr->ifr_name, IFNAMSIZ); ifrcopy = *ifr; my_ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy); flags = ifrcopy.ifr_flags; if ((flags & IFF_UP) == 0) continue; /* ignore if interface not up */ /* end get_ifi_info2 */ /* include get_ifi_info3 */ ifi = my_calloc(1, sizeof(struct ifi_info)); *ifipnext = ifi; /* prev points to this new one */ ifipnext = &ifi->ifi_next; /* pointer to next one goes here */ ifi->ifi_flags = flags; /* IFF_xxx values */ ifi->ifi_myflags = myflags; /* IFI_xxx values */ #if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU) Ioctl(sockfd, SIOCGIFMTU, &ifrcopy); ifi->ifi_mtu = ifrcopy.ifr_mtu; #else ifi->ifi_mtu = 0; #endif memcpy(ifi->ifi_name, ifr->ifr_name, IFI_NAME); ifi->ifi_name[IFI_NAME-1] = '\0'; /* If the sockaddr_dl is from a different interface, ignore it */ if (sdlname == NULL || strcmp(sdlname, ifr->ifr_name) != 0) idx = hlen = 0; ifi->ifi_index = idx; ifi->ifi_hlen = hlen; if (ifi->ifi_hlen > IFI_HADDR) ifi->ifi_hlen = IFI_HADDR; if (hlen) memcpy(ifi->ifi_haddr, haddr, ifi->ifi_hlen); /* end get_ifi_info3 */ /* include get_ifi_info4 */ switch (ifr->ifr_addr.sa_family) { case AF_INET: sinptr = (struct sockaddr_in *) &ifr->ifr_addr; ifi->ifi_addr = my_calloc(1, sizeof(struct sockaddr_in)); memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in)); #ifdef SIOCGIFBRDADDR if (flags & IFF_BROADCAST) { my_ioctl(sockfd, SIOCGIFBRDADDR, &ifrcopy); sinptr = (struct sockaddr_in *) &ifrcopy.ifr_broadaddr; ifi->ifi_brdaddr = my_calloc(1, sizeof(struct sockaddr_in)); memcpy(ifi->ifi_brdaddr, sinptr, sizeof(struct sockaddr_in)); } #endif #ifdef SIOCGIFDSTADDR if (flags & IFF_POINTOPOINT) { my_ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy); sinptr = (struct sockaddr_in *) &ifrcopy.ifr_dstaddr; ifi->ifi_dstaddr = my_calloc(1, sizeof(struct sockaddr_in)); memcpy(ifi->ifi_dstaddr, sinptr, sizeof(struct sockaddr_in)); } #endif break; case AF_INET6: sin6ptr = (struct sockaddr_in6 *) &ifr->ifr_addr; ifi->ifi_addr = my_calloc(1, sizeof(struct sockaddr_in6)); memcpy(ifi->ifi_addr, sin6ptr, sizeof(struct sockaddr_in6)); #ifdef SIOCGIFDSTADDR if (flags & IFF_POINTOPOINT) { my_ioctl(sockfd, SIOCGIFDSTADDR, &ifrcopy); sin6ptr = (struct sockaddr_in6 *) &ifrcopy.ifr_dstaddr; ifi->ifi_dstaddr = my_calloc(1, sizeof(struct sockaddr_in6)); memcpy(ifi->ifi_dstaddr, sin6ptr, sizeof(struct sockaddr_in6)); } #endif break; default: break; } } free(buf); return(ifihead); /* pointer to first structure in linked list */ }
static PyObject *Video_device_read_internal(Video_device *self, int queue) { if(!self->buffers) { ASSERT_OPEN; PyErr_SetString(PyExc_ValueError, "Buffers have not been created"); return NULL; } struct v4l2_buffer buffer; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(self->fd, VIDIOC_DQBUF, &buffer)) { return NULL; } #ifdef USE_LIBV4L PyObject *result = PyString_FromStringAndSize( self->buffers[buffer.index].start, buffer.bytesused); if(!result) { return NULL; } #else // Convert buffer from YUYV to RGB. // For the byte order, see: http://v4l2spec.bytesex.org/spec/r4339.htm // For the color conversion, see: http://v4l2spec.bytesex.org/spec/x2123.htm int length = buffer.bytesused * 6 / 4; PyObject *result = PyString_FromStringAndSize(NULL, length); if(!result) { return NULL; } char *rgb = PyString_AS_STRING(result); char *rgb_max = rgb + length; unsigned char *yuyv = self->buffers[buffer.index].start; #define CLAMP(c) ((c) <= 0 ? 0 : (c) >= 65025 ? 255 : (c) >> 8) while(rgb < rgb_max) { int u = yuyv[1] - 128; int v = yuyv[3] - 128; int uv = 100 * u + 208 * v; u *= 516; v *= 409; int y = 298 * (yuyv[0] - 16); rgb[0] = CLAMP(y + v); rgb[1] = CLAMP(y - uv); rgb[2] = CLAMP(y + u); y = 298 * (yuyv[2] - 16); rgb[3] = CLAMP(y + v); rgb[4] = CLAMP(y - uv); rgb[5] = CLAMP(y + u); rgb += 6; yuyv += 4; } #undef CLAMP #endif if(queue && my_ioctl(self->fd, VIDIOC_QBUF, &buffer)) { return NULL; } return result; }
int Video_in_Manager::ReadFrame() { if(this->fd<0) throw std::runtime_error("File not open"); if(this->buffers == NULL) throw std::runtime_error("Buffers have not been created"); struct v4l2_buffer buffer; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(this->fd, VIDIOC_DQBUF, &buffer, 10000)) { return 0; } unsigned char *rgbBuff = NULL; unsigned rgbBuffLen = 0; int ok = DecodeFrame((const unsigned char*)this->buffers[buffer.index].start, buffer.bytesused, this->pxFmt.c_str(), this->frameWidth, this->frameHeight, this->targetFmt.c_str(), &rgbBuff, &rgbBuffLen); //Return a frame, decoded or not pthread_mutex_lock(&this->lock); class FrameMetaData meta; meta.width = this->frameWidth; meta.height = this->frameHeight; if(ok && rgbBuff != NULL) { meta.fmt = this->targetFmt; meta.buffLen = rgbBuffLen; this->decodedFrameBuff.push_back(rgbBuff); } else { //Make a copy of un-decodable buffer to return unsigned char* buffOut = new unsigned char[buffer.bytesused]; memcpy(buffOut, this->buffers[buffer.index].start, buffer.bytesused); meta.fmt = this->pxFmt; meta.buffLen = buffer.bytesused; this->decodedFrameBuff.push_back(buffOut); } meta.sequence = buffer.sequence; meta.tv_sec = buffer.timestamp.tv_sec; meta.tv_usec = buffer.timestamp.tv_usec; this->decodedFrameMetaBuff.push_back(meta); while(this->decodedFrameBuff.size() > this->decodedFrameBuffMaxSize) { this->decodedFrameBuff.erase(this->decodedFrameBuff.begin()); this->decodedFrameMetaBuff.erase(this->decodedFrameMetaBuff.begin()); } pthread_mutex_unlock(&this->lock); //Queue buffer for next frame if(my_ioctl(this->fd, VIDIOC_QBUF, &buffer)) { throw std::runtime_error("VIDIOC_QBUF failed"); } return 1; }
static PyObject *Video_device_create_buffers(Video_device *self, PyObject *args) { int buffer_count; if(!PyArg_ParseTuple(args, "I", &buffer_count)) { return NULL; } ASSERT_OPEN; if(self->buffers) { PyErr_SetString(PyExc_ValueError, "Buffers are already created"); return NULL; } struct v4l2_requestbuffers reqbuf; reqbuf.count = buffer_count; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; if(my_ioctl(self->fd, VIDIOC_REQBUFS, &reqbuf)) { return NULL; } if(!reqbuf.count) { PyErr_SetString(PyExc_IOError, "Not enough buffer memory"); return NULL; } self->buffers = malloc(reqbuf.count * sizeof(struct buffer)); if(!self->buffers) { PyErr_NoMemory(); return NULL; } int i; for(i = 0; i < reqbuf.count; i++) { struct v4l2_buffer buffer; buffer.index = i; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(self->fd, VIDIOC_QUERYBUF, &buffer)) { return NULL; } self->buffers[i].length = buffer.length; self->buffers[i].start = v4l2_mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, buffer.m.offset); if(self->buffers[i].start == MAP_FAILED) { PyErr_SetFromErrno(PyExc_IOError); return NULL; } } self->buffer_count = i; Py_RETURN_NONE; }
int Video_in_Manager::StartDeviceInternal(int buffer_count = 10) { if(verbose) printf("StartDeviceInternal\n"); //Check this device has not already been start if(this->fd==-1) { throw std::runtime_error("Device not open"); } //Set other parameters for capture //TODO /* //Query current pixel format self.size_x, self.size_y, self.pixelFmt = self.video.get_format() //Set target frames per second self.fps = self.video.set_fps(reqFps) */ // Create a buffer to store image data in. This must be done before // calling 'start' if v4l2capture is compiled with libv4l2. Otherwise // raises IOError. if(this->pxFmt.length()==0) { //Get current pixel format //TODO int ret = GetFormatInternal(); if(!ret) throw std::runtime_error("Could not determine image format"); } struct v4l2_requestbuffers reqbuf; reqbuf.count = buffer_count; reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; if(my_ioctl(this->fd, VIDIOC_REQBUFS, &reqbuf)) { throw std::runtime_error("VIDIOC_REQBUFS failed"); } if(!reqbuf.count) { throw std::runtime_error("Not enough buffer memory"); } this->buffers = new struct buffer [reqbuf.count]; if(this->buffers == NULL) { throw std::runtime_error("Failed to allocate buffer memory"); } for(unsigned int i = 0; i < reqbuf.count; i++) { struct v4l2_buffer buffer; buffer.index = i; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(fd, VIDIOC_QUERYBUF, &buffer)) { throw std::runtime_error("VIDIOC_QUERYBUF failed"); } this->buffers[i].length = buffer.length; this->buffers[i].start = v4l2_mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buffer.m.offset); if(this->buffers[i].start == MAP_FAILED) { throw std::runtime_error("v4l2_mmap failed"); } } this->buffer_counts = reqbuf.count; // Send the buffer to the device. Some devices require this to be done // before calling 'start'. for(int i = 0; i < buffer_count; i++) { struct v4l2_buffer buffer; buffer.index = i; buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; if(my_ioctl(fd, VIDIOC_QBUF, &buffer)) { //This may fail with some devices but does not seem to be harmful. } } // Start the device. This lights the LED if it's a camera that has one. enum v4l2_buf_type type; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if(my_ioctl(fd, VIDIOC_STREAMON, &type)) { throw std::runtime_error("VIDIOC_STREAMON failed"); } this->Test(); this->deviceStarted = 1; if(verbose) printf("Started ok\n"); return 1; }