Beispiel #1
0
static int enum_frame_sizes(int fd, int pixfmt)
{
    int ret;
    struct v4l2_frmsizeenum fsize;

    memset(&fsize, 0, sizeof(struct v4l2_frmsizeenum));
    fsize.index = 0;
    fsize.pixel_format = pixfmt;
    while ((ret = ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize)) == 0) 
    {
        if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) 
        {
            printf("{ discrete: width = %u, height = %u }\n",
                   fsize.discrete.width, fsize.discrete.height);

            ret = enum_frame_intervals(fd, pixfmt,
                                       fsize.discrete.width, 
                                       fsize.discrete.height);
            if (ret != 0)
            {
                printf("  Unable to enumerate frame sizes.\n");
            }
        } 
        else if (fsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) 
        {
            printf("{ continuous: min { width = %u, height = %u } .. "
                   "max { width = %u, height = %u } }\n",
                   fsize.stepwise.min_width, fsize.stepwise.min_height,
                   fsize.stepwise.max_width, fsize.stepwise.max_height);
            printf("  Refusing to enumerate frame intervals.\n");
            break;
        } 
        else if (fsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) 
        {
            printf("{ stepwise: min { width = %u, height = %u } .. "
                   "max { width = %u, height = %u } / "
                   "stepsize { width = %u, height = %u } }\n",
                   fsize.stepwise.min_width, fsize.stepwise.min_height,
                   fsize.stepwise.max_width, fsize.stepwise.max_height,
                   fsize.stepwise.step_width, fsize.stepwise.step_height);
            printf("  Refusing to enumerate frame intervals.\n");
            break;
        }
        fsize.index++;
    }

    if (ret != 0 && errno != EINVAL) 
    {
        printf("ERROR enumerating frame sizes: %d\n", errno);
        return errno;
    }

    return 0;
}
/* enumerate frame sizes
 * args:
 * listVidFormats: array of VidFormats (list of video formats)
 * pixfmt: v4l2 pixel format that we want to list frame sizes for
 * fmtind: format list current index
 * width: pointer to integer containing the selected video width
 * height: pointer to integer containing the selected video height
 * fd: device file descriptor
 * 
 * returns 0 if enumeration succeded or errno otherwise               */
static int enum_frame_sizes(VidFormats *listVidFormats, __u32 pixfmt, int fmtind, int *width, int *height, int fd)
{
	int ret=0;
	int fsizeind=0; /*index for supported sizes*/
	listVidFormats[fmtind-1].listVidCap = NULL;
	struct v4l2_frmsizeenum fsize;

	memset(&fsize, 0, sizeof(fsize));
	fsize.index = 0;
	fsize.pixel_format = pixfmt;
	while ((ret = xioctl(fd, VIDIOC_ENUM_FRAMESIZES, &fsize)) == 0) 
	{
		fsize.index++;
		if (fsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) 
		{
			printf("{ discrete: width = %u, height = %u }\n",
				fsize.discrete.width, fsize.discrete.height);
			
			fsizeind++;
			listVidFormats[fmtind-1].listVidCap = (VidCap*) realloc(
                listVidFormats[fmtind-1].listVidCap,
                sizeof(VidCap) * fsizeind);
			
			listVidFormats[fmtind-1].listVidCap[fsizeind-1].width = fsize.discrete.width;
			listVidFormats[fmtind-1].listVidCap[fsizeind-1].height = fsize.discrete.height;
			
			ret = enum_frame_intervals(listVidFormats, 
				pixfmt,
				fsize.discrete.width, 
				fsize.discrete.height,
				fmtind, 
				fsizeind, 
				fd);
			
			if (ret != 0) perror("  Unable to enumerate frame sizes");
		} 
		else if (fsize.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) 
		{
			printf("{ continuous: min { width = %u, height = %u } .. "
				"max { width = %u, height = %u } }\n",
				fsize.stepwise.min_width, fsize.stepwise.min_height,
				fsize.stepwise.max_width, fsize.stepwise.max_height);
			printf("  will not enumerate frame intervals.\n");
		} 
		else if (fsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) 
		{
			printf("{ stepwise: min { width = %u, height = %u } .. "
				"max { width = %u, height = %u } / "
				"stepsize { width = %u, height = %u } }\n",
				fsize.stepwise.min_width, fsize.stepwise.min_height,
				fsize.stepwise.max_width, fsize.stepwise.max_height,
				fsize.stepwise.step_width, fsize.stepwise.step_height);
			printf("  will not enumerate frame intervals.\n");
		} 
		else 
		{
			fprintf(stderr,"  fsize.type not supported: %d\n", fsize.type);
			fprintf(stderr,"     (Discrete: %d   Continuous: %d  Stepwise: %d)\n",
				V4L2_FRMSIZE_TYPE_DISCRETE,
				V4L2_FRMSIZE_TYPE_CONTINUOUS,
				V4L2_FRMSIZE_TYPE_STEPWISE);
		}
	}
	if (ret != 0 && errno != EINVAL) 
	{
		perror("VIDIOC_ENUM_FRAMESIZES - Error enumerating frame sizes");
		return errno;
	} 
	else if ((ret != 0) && (fsizeind == 0)) 
	{		
		/* ------ gspca doesn't enumerate frame sizes ------ */
		/*       negotiate with VIDIOC_TRY_FMT instead       */
		
		fsizeind++;
		struct v4l2_format fmt;
		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		fmt.fmt.pix.width = *width;
		fmt.fmt.pix.height = *height;
		fmt.fmt.pix.pixelformat = pixfmt;
		fmt.fmt.pix.field = V4L2_FIELD_ANY;
		ret = xioctl(fd, VIDIOC_TRY_FMT, &fmt);
		/*use the returned values*/
		*width = fmt.fmt.pix.width;
		*height = fmt.fmt.pix.height;
		printf("{ ?GSPCA? : width = %u, height = %u }\n", *width, *height);
		printf("fmtind:%i fsizeind: %i\n",fmtind,fsizeind);
		if(listVidFormats[fmtind-1].listVidCap == NULL) 
		{
			listVidFormats[fmtind-1].listVidCap = (VidCap*) realloc(
                listVidFormats[fmtind-1].listVidCap,
                sizeof(VidCap) * fsizeind);
/*			listVidFormats[fmtind-1].listVidCap[0].framerate_num = NULL;
			listVidFormats[fmtind-1].listVidCap[0].framerate_num = g_renew( int,
				listVidFormats[fmtind-1].listVidCap[0].framerate_num,
				1);
			listVidFormats[fmtind-1].listVidCap[0].framerate_denom = NULL;
			listVidFormats[fmtind-1].listVidCap[0].framerate_denom = g_renew( int,
				listVidFormats[fmtind-1].listVidCap[0].framerate_denom,
				1);*/
		} 
		else
		{
			fprintf(stderr,"assert failed: listVidCap not Null\n");
			return (-2);
		}
		listVidFormats[fmtind-1].listVidCap[0].width = *width;
		listVidFormats[fmtind-1].listVidCap[0].height = *height;
		listVidFormats[fmtind-1].listVidCap[0].framerate_num[0] = 1;
		listVidFormats[fmtind-1].listVidCap[0].framerate_denom[0] = 25;
		listVidFormats[fmtind-1].listVidCap[0].numb_frates = 1;
	}
	
	listVidFormats[fmtind-1].numb_res=fsizeind;
	return 0;
}