I'm trying to use V4L2 api to enumertate supported frame size and frame rate of webcam device. I try to do it with the following code without success. The ioctl function always returns -1.
#include <stdio.h>
#include <fcntl.h>
#include "linux/videodev2.h"
int main(int argc, char **argv) {
int fd = open("/dev/video0", O_RDWR);
struct v4l2_frmivalenum frmsize;
memset(&frmsize, 0, sizeof (struct v4l2_frmsizeenum));
ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS , &frmsize);
printf("%u \n", frmsize.he);
return 0;
}
You should set the in parameter before ioctl VIDIOC_ENUM_FRAMESIZES to get frame sizes :
Table A.34. struct v4l2_frmivalenum
__u32 index IN: Index of the given frame interval in the enumeration.
__u32 pixel_format IN: Pixel format for which the frame intervals are enumerated.
__u32 width IN: Frame width for which the frame intervals are enumerated.
__u32 height IN: Frame height for which the frame intervals are enumerated.
and ioctl VIDIOC_ENUM_FRAMEINTERVALS to get frame intervals :
Table A.31. struct v4l2_frmsizeenum
__u32 index IN: Index of the given frame size in the enumeration.
__u32 pixel_format IN: Pixel format for which the frame sizes are enumerated.
Then an implementation that enumerates frame sizes and frame intervals could be :
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "linux/videodev2.h"
void printFrameInterval(int fd, unsigned int fmt, unsigned int width, unsigned int height)
{
struct v4l2_frmivalenum frmival;
memset(&frmival,0,sizeof(frmival));
frmival.pixel_format = fmt;
frmival.width = width;
frmival.height = height;
while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == 0)
{
if (frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE)
printf("[%dx%d] %f fps\n", width, height, 1.0*frmival.discrete.denominator/frmival.discrete.numerator);
else
printf("[%dx%d] [%f,%f] fps\n", width, height, 1.0*frmival.stepwise.max.denominator/frmival.stepwise.max.numerator, 1.0*frmival.stepwise.min.denominator/frmival.stepwise.min.numerator);
frmival.index++;
}
}
int main(int argc, char **argv) {
unsigned int width=0, height=0;;
int fd = open("/dev/video0", O_RDWR);
struct v4l2_frmsizeenum frmsize;
memset(&frmsize,0,sizeof(frmsize));
frmsize.pixel_format = V4L2_PIX_FMT_JPEG;
while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0)
{
if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE)
{
printFrameInterval(fd, frmsize.pixel_format, frmsize.discrete.width, frmsize.discrete.height);
}
else
{
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);
}
frmsize.index++;
}
return 0;
}