def _enum_frame_sizes(self, pixel_format): # not handling types other than V4L2_FRMSIZE_TYPE_DISCRETE return self._enum_common( v4l2.VIDIOC_ENUM_FRAMESIZES, lambda idx: v4l2.v4l2_frmsizeenum( index=idx, pixel_format=pixel_format, ))
def get_outputs(pixel_format): vd = open('/dev/video0', 'rb+', buffering=0) qctrl = v4l2.v4l2_frmsizeenum() qctrl.type = v4l2.V4L2_BUF_TYPE_VIDEO_OUTPUT qctrl.index = 0 qctrl.pixel_format = pixel_format while qctrl.index < 10: # TODO: better loop try: fcntl.ioctl(vd, v4l2.VIDIOC_ENUM_FRAMESIZES, qctrl) if (qctrl.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE): get_detailed_outputs(vd, qctrl.pixel_format, qctrl.discrete.width, qctrl.discrete.height) else: # TODO: translate to Python, can't test because no device with stepsize ''' for (width=frmsize.stepwise.min_width; width< frmsize.stepwise.max_width; width+=frmsize.stepwise.step_width) for (height=frmsize.stepwise.min_height; height< frmsize.stepwise.max_height; height+=frmsize.stepwise.step_height) printFrameInterval(fd, frmsize.pixel_format, width, height); ''' except: pass qctrl.index += 1 vd.close()
def get_frame_sizes(self, fourcc): b = v4l2.v4l2_frmsizeenum() b.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE b.pixel_format = fourcc sizes = [] while True: try: fcntl.ioctl(self, v4l2.VIDIOC_ENUM_FRAMESIZES, b) if b.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: sizes.append((b.discrete.width, b.discrete.height)) else: sizes.append( (b.stepwise.min_width, b.stepwise.max_width, b.stepwise.step_width, b.stepwise.min_height, b.stepwise.max_height, b.stepwise.step_height)) b.index += 1 # pylint: disable=no-member except OSError: break return sizes
def get_possible_resolutions(self): import v4l2 from fcntl import ioctl fd = os.open(self.__device_path, os.O_RDWR) fmt = v4l2.v4l2_fmtdesc() fmt.type = v4l2.V4L2_BUF_TYPE_VIDEO_CAPTURE resolutions = set() # Special thanks to @Rirush for this solution while True: try: ioctl(fd, v4l2.VIDIOC_ENUM_FMT, fmt) except OSError: break frm = v4l2.v4l2_frmsizeenum() frm.pixel_format = fmt.pixelformat while True: try: ioctl(fd, v4l2.VIDIOC_ENUM_FRAMESIZES, frm) except OSError: break frm.index += 1 resolutions.add((frm.discrete.width, frm.discrete.height)) fmt.index += 1 os.close(fd) return resolutions
def get_camera_framesize(device, fmtdesc, index): vd = open(device) res = v4l2.v4l2_frmsizeenum() res.pixel_format = fmtdesc.pixelformat res.index = index try: fcntl.ioctl(vd, v4l2.VIDIOC_ENUM_FRAMESIZES, res) except: res = None # if res.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: # print(res.discrete.height) vd.close() return res
def get_framesizes(self, pixel_format = v4l2.V4L2_PIX_FMT_Y16): framesizes = [] framesize = v4l2.v4l2_frmsizeenum() framesize.index = 0 framesize.pixel_format = pixel_format while True: try: fcntl.ioctl(self.vd, v4l2.VIDIOC_ENUM_FRAMESIZES, framesize) framesizes.append((framesize.discrete.width, framesize.discrete.height)) framesize.index += 1 except Exception as e: break return framesizes
def EnumerateFormats(self): fmtdesc = self.FormatDescript() self.listValidFormats = list() for key in fmtdesc: fse = v4l2.v4l2_frmsizeenum() for i in range(10): fse.index = i fse.pixel_format = fmtdesc[key] try: xioctl(self.vd, v4l2.VIDIOC_ENUM_FRAMESIZES, fse) except: break fpslist = self.GetFrameRate(fse.pixel_format, fse.discrete.width, fse.discrete.height) for fps in fpslist: self.listValidFormats.append((key, fse.discrete.width, fse.discrete.height, fps)) return self.listValidFormats
def getCameraFormats(number): name = '/dev/video{}'.format(number) formats = [] try: with open(name, 'r') as fd: fmt = v4l2.v4l2_fmtdesc() fmt.index = 0 fmt.type = v4l2.V4L2_CAP_VIDEO_CAPTURE while fcntl.ioctl(fd, v4l2.VIDIOC_ENUM_FMT, fmt) == 0: pixelformat = '{:c}{:c}{:c}{:c}'.format( fmt.pixelformat & 255, (fmt.pixelformat >> 8) & 255, (fmt.pixelformat >> 16) & 255, fmt.pixelformat >> 24) frmsize = v4l2.v4l2_frmsizeenum() frmsize.index = 0 frmsize.pixel_format = fmt.pixelformat while fcntl.ioctl(fd, v4l2.VIDIOC_ENUM_FRAMESIZES, frmsize) == 0: if frmsize.type != v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: break width = frmsize.discrete.width height = frmsize.discrete.height frmival = v4l2.v4l2_frmivalenum() frmival.index = 0 frmival.pixel_format = fmt.pixelformat frmival.width = width frmival.height = height try: while fcntl.ioctl(fd, v4l2.VIDIOC_ENUM_FRAMEINTERVALS, frmival) == 0: if frmival.type != v4l2.V4L2_FRMIVAL_TYPE_DISCRETE: break fps = int(frmival.discrete.denominator / frmival.discrete.numerator) formats.append((pixelformat, width, height, fps)) frmival.index += 1 except: None frmsize.index += 1 fmt.index += 1 except IOError as e: None return formats
def _getSupportedResolutions(self): """Query the camera for supported resolutions for a given pixel_format. Data is returned in a list of dictionaries with supported pixel formats as the following example shows: resolution['pixelformat'] = "YUYV" resolution['description'] = "(YUV 4:2:2 (YUYV))" resolution['resolutions'] = [[width, height], [640, 480], [1280, 720] ] If we are unable to gather any information from the driver, then we return YUYV and 640x480 which seems to be a safe default. Per the v4l2 spec the ioctl used here is experimental but seems to be well supported. """ try: device = '/dev/video%d' % self.number_of_video_device supported_formats = self.__getPixelFormats(device) if not supported_formats: return None for supported_format in supported_formats: resolutions = [] framesize = v4l2.v4l2_frmsizeenum() framesize.index = 0 framesize.pixel_format = supported_format['pixelformat_int'] with open(device, 'r') as vd: try: cp = v4l2.v4l2_capability() fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp) self.cameraName = cp.card while fcntl.ioctl(vd, v4l2.VIDIOC_ENUM_FRAMESIZES, framesize) == 0: if framesize.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: resolutions.append([ framesize.discrete.width, framesize.discrete.height ]) # for continuous and stepwise, let's just use min and # max they use the same structure and only return # one result elif framesize.type == v4l2.V4L2_FRMSIZE_TYPE_CONTINUOUS or framesize.type == v4l2.V4L2_FRMSIZE_TYPE_STEPWISE: if hasattr(framesize.stepwise, 'max_width'): max_width = framesize.stepwise.max_width else: max_width = framesize.stepwise.max_height width = framesize.stepwise.min_width height = framesize.stepwise.min_height stepWidth = framesize.stepwise.step_width stepHeight = framesize.stepwise.step_height widthCounter = 1 heightCounter = 1 ########## Low resolution ######### if self._calcMCD( 640, stepWidth ) == stepWidth and self._calcMCD( 480, stepHeight) == stepHeight: resolutions.append([640L, 480L]) ########## High resolution ######### if self._calcMCD( 1280L, stepWidth ) == stepWidth and self._calcMCD( 720L, stepHeight) == stepHeight: resolutions.append([1280L, 720L]) break framesize.index = framesize.index + 1 except IOError as e: # EINVAL is the ioctl's way of telling us that there are no # more formats, so we ignore it if e.errno != errno.EINVAL: self._logger.error( "Unable to determine supported framesizes (resolutions), this may be a driver issue." ) return None supported_format['resolutions'] = resolutions for resolution in supported_format['resolutions']: frameinterval = v4l2.v4l2_frmivalenum() frameinterval.index = 0 frameinterval.pixel_format = supported_format[ 'pixelformat_int'] frameinterval.width = resolution[0] frameinterval.height = resolution[1] framerates = [] with open(device, 'r') as fd: try: while fcntl.ioctl( fd, v4l2.VIDIOC_ENUM_FRAMEINTERVALS, frameinterval) != -1: if frameinterval.type == v4l2.V4L2_FRMIVAL_TYPE_DISCRETE: framerates.append( str(frameinterval.discrete. denominator) + '/' + str(frameinterval.discrete. numerator)) # for continuous and stepwise, let's just use min and # max they use the same structure and only return # one result stepval = 0 if frameinterval.type == v4l2.V4L2_FRMIVAL_TYPE_CONTINUOUS: stepval = 1 minval = frameinterval.stepwise.min.denominator / frameinterval.stepwise.min.numerator maxval = frameinterval.stepwise.max.denominator / frameinterval.stepwise.max.numerator if stepval == 0: stepval = frameinterval.stepwise.step.denominator / frameinterval.stepwise.step.numerator numerator = frameinterval.stepwise.max.numerator denominator = frameinterval.stepwise.max.denominator while numerator <= frameinterval.stepwise.min.numerator: while denominator <= frameinterval.stepwise.min.denominator: framerates.append( str(denominator) + '/' + str(numerator)) denominator = denominator + frameinterval.stepwise.step.denominator numerator = numerator + frameinterval.stepwise.step.numerator denominator = frameinterval.stepwise.max.denominator elif framesize.type == v4l2.V4L2_FRMSIZE_TYPE_CONTINUOUS or\ framesize.type == v4l2.V4L2_FRMSIZE_TYPE_STEPWISE: minval = frameinterval.stepwise.min.denominator / frameinterval.stepwise.min.numerator maxval = frameinterval.stepwise.max.denominator / frameinterval.stepwise.max.numerator if stepval == 0: stepval = frameinterval.stepwise.step.denominator / frameinterval.stepwise.step.numerator for cval in range(minval, maxval): framerates.append('1/' + str(cval)) break frameinterval.index = frameinterval.index + 1 except IOError as e: # EINVAL is the ioctl's way of telling us that there are no # more formats, so we ignore it if e.errno != errno.EINVAL: self._logger.error( "Unable to determine supported framerates (resolutions), this may be a driver issue." ) resolution.append(framerates) temp = [] #clean resolutions without FPS: some broken cameras has this configuration for resolution in supported_format['resolutions']: if len(resolution[2]) > 0: temp.append(resolution) supported_format['resolutions'] = temp try: if supported_format['resolutions']: return supported_formats else: return None except: return None except Exception: self._logger.info( 'Camera error: it is not posible to get the camera capabilities', exc_info=True) return None
def _getSupportedResolutions(self): """Query the camera for supported resolutions for a given pixel_format. Data is returned in a list of dictionaries with supported pixel formats as the following example shows: resolution['pixelformat'] = "YUYV" resolution['description'] = "(YUV 4:2:2 (YUYV))" resolution['resolutions'] = [[width, height], [640, 480], [1280, 720] ] If we are unable to gather any information from the driver, then we return YUYV and 640x480 which seems to be a safe default. Per the v4l2 spec the ioctl used here is experimental but seems to be well supported. """ try: device = '/dev/video%d' % self.number_of_video_device supported_formats = self.__getPixelFormats(device) if not supported_formats: resolution = {} #resolution['description'] = "YUYV" #resolution['pixelformat'] = "YUYV" #resolution['resolutions'] = [[640, 480]] #resolution['pixelformat_int'] = v4l2.v4l2_fmtdesc().pixelformat supported_formats.append(resolution) return None for supported_format in supported_formats: resolutions = [] framesize = v4l2.v4l2_frmsizeenum() framesize.index = 0 framesize.pixel_format = supported_format['pixelformat_int'] with open(device, 'r') as vd: try: cp = v4l2.v4l2_capability() fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp) self.cameraName = cp.card while fcntl.ioctl(vd,v4l2.VIDIOC_ENUM_FRAMESIZES,framesize) == 0: if framesize.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: resolutions.append([framesize.discrete.width, framesize.discrete.height]) # for continuous and stepwise, let's just use min and # max they use the same structure and only return # one result elif framesize.type == v4l2.V4L2_FRMSIZE_TYPE_CONTINUOUS or framesize.type == v4l2.V4L2_FRMSIZE_TYPE_STEPWISE: if hasattr(framesize.stepwise, 'max_width'): max_width = framesize.stepwise.max_width else: max_width = framesize.stepwise.max_height width = framesize.stepwise.min_width height = framesize.stepwise.min_height stepWidth = framesize.stepwise.step_width stepHeight = framesize.stepwise.step_height widthCounter = 1 heightCounter = 1 """while width <= max_width: while height <= framesize.stepwise.max_height: resolutions.append([width,height]) height = height * stepHeight width = width * stepWidth height = framesize.stepwise.min_height """ ########## Low resolution ######### if(self._calcMCD(640,stepWidth) == stepWidth): if(self._calcMCD(480,stepHeight) == stepHeight): resolutions.append([640L,480L]) ########## High resolution ######### if(self._calcMCD(1280L,stepWidth) == stepWidth): if(self._calcMCD(720L,stepHeight) == stepHeight): resolutions.append([1280L,720L]) break framesize.index = framesize.index + 1 except IOError as e: # EINVAL is the ioctl's way of telling us that there are no # more formats, so we ignore it if e.errno != errno.EINVAL: self._logger.error("Unable to determine supported framesizes (resolutions), this may be a driver issue.") return None
def _getSupportedResolutions(self): """Query the camera for supported resolutions for a given pixel_format. Data is returned in a list of dictionaries with supported pixel formats as the following example shows: resolution['pixelformat'] = "YUYV" resolution['description'] = "(YUV 4:2:2 (YUYV))" resolution['resolutions'] = [[width, height], [640, 480], [1280, 720] ] If we are unable to gather any information from the driver, then we return YUYV and 640x480 which seems to be a safe default. Per the v4l2 spec the ioctl used here is experimental but seems to be well supported. """ try: device = '/dev/video%d' % self.number_of_video_device supported_formats = self.__getPixelFormats(device) if not supported_formats: return None for supported_format in supported_formats: resolutions = [] framesize = v4l2.v4l2_frmsizeenum() framesize.index = 0 framesize.pixel_format = supported_format['pixelformat_int'] with open(device, 'r') as vd: try: cp = v4l2.v4l2_capability() fcntl.ioctl(vd, v4l2.VIDIOC_QUERYCAP, cp) self.cameraName = cp.card while fcntl.ioctl(vd,v4l2.VIDIOC_ENUM_FRAMESIZES,framesize) == 0: if framesize.type == v4l2.V4L2_FRMSIZE_TYPE_DISCRETE: resolutions.append([framesize.discrete.width, framesize.discrete.height]) # for continuous and stepwise, let's just use min and # max they use the same structure and only return # one result elif framesize.type == v4l2.V4L2_FRMSIZE_TYPE_CONTINUOUS or framesize.type == v4l2.V4L2_FRMSIZE_TYPE_STEPWISE: if hasattr(framesize.stepwise, 'max_width'): max_width = framesize.stepwise.max_width else: max_width = framesize.stepwise.max_height width = framesize.stepwise.min_width height = framesize.stepwise.min_height stepWidth = framesize.stepwise.step_width stepHeight = framesize.stepwise.step_height widthCounter = 1 heightCounter = 1 ########## Low resolution ######### if self._calcMCD(640,stepWidth) == stepWidth and self._calcMCD(480,stepHeight) == stepHeight: resolutions.append([640L,480L]) ########## High resolution ######### if self._calcMCD(1280L,stepWidth) == stepWidth and self._calcMCD(720L,stepHeight) == stepHeight: resolutions.append([1280L,720L]) break framesize.index = framesize.index + 1 except IOError as e: # EINVAL is the ioctl's way of telling us that there are no # more formats, so we ignore it if e.errno != errno.EINVAL: self._logger.error("Unable to determine supported framesizes (resolutions), this may be a driver issue.") return None supported_format['resolutions'] = resolutions for resolution in supported_format['resolutions']: frameinterval = v4l2.v4l2_frmivalenum() frameinterval.index = 0 frameinterval.pixel_format = supported_format['pixelformat_int'] frameinterval.width = resolution[0]; frameinterval.height = resolution[1]; framerates = [] with open(device, 'r') as fd: try: while fcntl.ioctl(fd,v4l2.VIDIOC_ENUM_FRAMEINTERVALS,frameinterval) != -1: if frameinterval.type == v4l2.V4L2_FRMIVAL_TYPE_DISCRETE: framerates.append(str(frameinterval.discrete.denominator) + '/' + str(frameinterval.discrete.numerator)) # for continuous and stepwise, let's just use min and # max they use the same structure and only return # one result stepval = 0 if frameinterval.type == v4l2.V4L2_FRMIVAL_TYPE_CONTINUOUS: stepval = 1 minval = frameinterval.stepwise.min.denominator/frameinterval.stepwise.min.numerator maxval = frameinterval.stepwise.max.denominator/frameinterval.stepwise.max.numerator if stepval == 0: stepval = frameinterval.stepwise.step.denominator/frameinterval.stepwise.step.numerator numerator = frameinterval.stepwise.max.numerator denominator = frameinterval.stepwise.max.denominator while numerator <= frameinterval.stepwise.min.numerator: while denominator <= frameinterval.stepwise.min.denominator: framerates.append(str(denominator) + '/' + str(numerator)) denominator = denominator + frameinterval.stepwise.step.denominator numerator = numerator + frameinterval.stepwise.step.numerator denominator = frameinterval.stepwise.max.denominator elif framesize.type == v4l2.V4L2_FRMSIZE_TYPE_CONTINUOUS or\ framesize.type == v4l2.V4L2_FRMSIZE_TYPE_STEPWISE: minval = frameinterval.stepwise.min.denominator/frameinterval.stepwise.min.numerator maxval = frameinterval.stepwise.max.denominator/frameinterval.stepwise.max.numerator if stepval == 0: stepval = frameinterval.stepwise.step.denominator/frameinterval.stepwise.step.numerator for cval in range(minval,maxval): framerates.append('1/' + str(cval)) break frameinterval.index = frameinterval.index + 1 except IOError as e: # EINVAL is the ioctl's way of telling us that there are no # more formats, so we ignore it if e.errno != errno.EINVAL: self._logger.error("Unable to determine supported framerates (resolutions), this may be a driver issue.") resolution.append(framerates) temp = [] #clean resolutions without FPS: some broken cameras has this configuration for resolution in supported_format['resolutions']: if len(resolution[2]) > 0: temp.append(resolution) supported_format['resolutions'] = temp try: if supported_format['resolutions']: return supported_formats else: return None except: return None except Exception: self._logger.info('Camera error: it is not posible to get the camera capabilities', exc_info=True) return None