v4l2: get framerates

Retrieving information on the possible frame rates for a given pixel format (RGB, YUYV, …) and a given frame size (640*480, …) using v4l2 should be simple. However, it took me some time to find the appropriate section in the documentation. In case you already have a file descriptor fd for the webcam device, this snippet illustrates the usage

		struct v4l2_frmivalenum temp;
		memset(&temp, 0, sizeof(temp));
		temp.pixel_format = V4L2_PIX_FMT_YUYV;
		temp.width = 640;
		temp.height = 480;

		v4l2_ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &temp);
		if (temp.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
			while (v4l2_ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &temp) != -1) {
				cout << float(temp.discrete.denominator)/temp.discrete.numerator << " fps" << endl;
				temp.index += 1;
			}
		}
		float stepval = 0;
		if (temp.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
			stepval = 1;
		}
		if (temp.type == V4L2_FRMIVAL_TYPE_STEPWISE || temp.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
			float minval = float(temp.stepwise.min.numerator)/temp.stepwise.min.denominator;
			float maxval = float(temp.stepwise.max.numerator)/temp.stepwise.max.denominator;
			if (stepval == 0) {
				stepval = float(temp.stepwise.step.numerator)/temp.stepwise.step.denominator;
			}
			for (float cval = minval; cval <= maxval; cval += stepval) {
				cout << 1/cval << " fps" << endl;
			}
		}

The mix of numerator and denominator is caused by the way v4l2 stores the information. The API uses frame intervals instead of frame rates.

Leave a comment

Your email address will not be published.