示例#1
0
int src_v4l2_set_control(src_t *src, struct v4l2_queryctrl *queryctrl)
{
	src_v4l2_t *s = (src_v4l2_t *) src->state;
	struct v4l2_control control;
	struct v4l2_querymenu querymenu;
	char *sv;
	int iv;
	
	if(queryctrl->flags & V4L2_CTRL_FLAG_DISABLED) return(0);
	if(src_get_option_by_name(src->option, (char *) queryctrl->name, &sv))
		return(0);
	
	memset(&querymenu, 0, sizeof(querymenu));
	memset(&control, 0, sizeof(control));
	
	control.id = queryctrl->id;
	
	switch(queryctrl->type)
	{
	case V4L2_CTRL_TYPE_INTEGER:
		
		/* Convert the value to an integer. */
		iv = atoi(sv);
		
		/* Is the value a precentage? */
		if(strchr(sv, '%'))
		{
			/* Adjust the precentage to fit the controls range. */
			iv = SCALE(queryctrl->minimum, queryctrl->maximum,
			           0, 100, iv);
		}
		
		MSG("Setting %s to %i (%i%%).", queryctrl->name, iv,
		    SCALE(0, 100, queryctrl->minimum, queryctrl->maximum, iv));
		
		if(iv < queryctrl->minimum || iv > queryctrl->maximum)
			WARN("Value is out of range. Setting anyway.");
		
		control.value = iv;
		ioctl(s->fd, VIDIOC_S_CTRL, &control);
		break;
	
	case V4L2_CTRL_TYPE_BOOLEAN:
		
		iv = -1;
		if(!strcasecmp(sv, "1") || !strcasecmp(sv, "true")) iv = 1;
		if(!strcasecmp(sv, "0") || !strcasecmp(sv, "false")) iv = 0;
		
		if(iv == -1)
		{
			WARN("Unknown boolean value '%s' for %s.",
			     sv, queryctrl->name);
			return(-1);
		}
		
		MSG("Setting %s to %s (%i).", queryctrl->name, sv, iv);
		
		control.value = iv;
		ioctl(s->fd, VIDIOC_S_CTRL, &control);
		
		break;
	
	case V4L2_CTRL_TYPE_MENU:
		
		/* Scan for a matching value. */
		querymenu.id = queryctrl->id;
		
		for(iv = queryctrl->minimum; iv <= queryctrl->maximum; iv++)
		{
			querymenu.index = iv;
			
			if(ioctl(s->fd, VIDIOC_QUERYMENU, &querymenu))
			{
				ERROR("Error querying menu.");
				continue;
			}
			
			if(!strncasecmp((char *) querymenu.name, sv, 32))
				break;
		}
		
		if(iv > queryctrl->maximum)
		{
			MSG("Unknown value '%s' for %s.", sv, queryctrl->name);
			return(-1);
		}
		
		MSG("Setting %s to %s (%i).",
		    queryctrl->name, querymenu.name, iv);
		
		control.value = iv;
		ioctl(s->fd, VIDIOC_S_CTRL, &control);
		
		break;
	
	case V4L2_CTRL_TYPE_BUTTON:
		
		MSG("Triggering %s control.", queryctrl->name);
		ioctl(s->fd, VIDIOC_S_CTRL, &control);
		
		break;
	
	default:
		WARN("Not setting unknown control type %i (%s).",
		     queryctrl->name);
		break;
	}
	
	return(0);
}
示例#2
0
int src_v4l_set_picture(src_t *src, int fd, struct video_capability *vd)
{
	src_v4l_t *s = (src_v4l_t *) src->state;
	struct video_picture vp;
	int v4l_pal;
	char *value;
	
	if(ioctl(fd, VIDIOCGPICT, &vp) < 0)
	{
		ERROR("Error getting picture information.");
		ERROR("VIDIOCGPICT: %s", strerror(errno));
		return(-1);
	}
	
	if(src->list & SRC_LIST_CONTROLS)
	{
		int i;
		
		HEAD("--- Avaliable controls:");
		
		for(i = 0; i < 5; i++)
		{
			char *name;
			int value;
			char t[64];
			
			switch(i)
			{
			case 0:
				name = "brightness";
				value = vp.brightness;
				break;
			case 1:
				name = "hue";
				value = vp.hue;
				break;
			case 2:
				name = "colour";
				value = vp.colour;
				break;
			case 3:
				name = "contrast";
				value = vp.contrast;
				break;
			case 4:
				name = "whiteness";
				value = vp.whiteness;
				break;
			}
			
			snprintf(t, 63, "%i (%i%%)",
			        SCALE(-100, 100, 0x0000, 0xFFFF, vp.brightness),
			        SCALE(0, 100, 0x0000, 0xFFFF, vp.brightness));
			
			MSG("%-25s %-15s 100 - -100", name, t);
		}
	}
	
	if(!src_get_option_by_name(src->option, "brightness", &value))
		vp.brightness = SCALE(0x0000, 0xFFFF, -100, 100, atoi(value));
	
	if(!src_get_option_by_name(src->option, "hue", &value))
		vp.hue        = SCALE(0x0000, 0xFFFF, -100, 100, atoi(value));
	
	if(!src_get_option_by_name(src->option, "colour", &value))
		vp.colour     = SCALE(0x0000, 0xFFFF, -100, 100, atoi(value));
	
	if(!src_get_option_by_name(src->option, "contrast", &value))
		vp.contrast   = SCALE(0x0000, 0xFFFF, -100, 100, atoi(value));
	
	if(!src_get_option_by_name(src->option, "whiteness", &value))
		vp.whiteness  = SCALE(0x0000, 0xFFFF, -100, 100, atoi(value));
	
	/* MJPEG devices are a special case... */
	if(vd->type & VID_TYPE_MJPEG_ENCODER)
	{
		WARN("Device is MJPEG only. Forcing JPEG palette.");
		src->palette = SRC_PAL_JPEG;
	}
	
	if(src->palette == SRC_PAL_JPEG && !(vd->type & VID_TYPE_MJPEG_ENCODER))
	{
		ERROR("MJPEG palette requsted for a non-MJPEG device.");
		return(-1);
	}
	
	if(src->palette == SRC_PAL_JPEG)
	{
		struct mjpeg_params mparm;
		
		if(ioctl(s->fd, MJPIOC_G_PARAMS, &mparm))
		{
			ERROR("Error querying video parameters.");
			ERROR("MJPIOC_G_PARAMS: %s", strerror(errno));
			return(-1);
		}
		
		DEBUG("%s: Video parameters...", src->source);
		DEBUG("major_version  = %i", mparm.major_version);
		DEBUG("minor_version  = %i", mparm.minor_version);
		DEBUG("input          = %i", mparm.input);
		DEBUG("norm           = %i", mparm.norm);
		DEBUG("decimation     = %i", mparm.decimation);
		DEBUG("HorDcm         = %i", mparm.HorDcm);
		DEBUG("VerDcm         = %i", mparm.VerDcm);
		DEBUG("TmpDcm         = %i", mparm.TmpDcm);
		DEBUG("field_per_buff = %i", mparm.field_per_buff);
		DEBUG("img_x          = %i", mparm.img_x);
		DEBUG("img_y          = %i", mparm.img_y);
		DEBUG("img_width      = %i", mparm.img_width);
		DEBUG("img_height     = %i", mparm.img_height);
		DEBUG("quality        = %i", mparm.quality);
		DEBUG("odd_even       = %i", mparm.odd_even);
		DEBUG("APPn           = %i", mparm.APPn);
		DEBUG("APP_len        = %i", mparm.APP_len);
		DEBUG("APP_data       = \"%s\"", mparm.APP_data);
		DEBUG("COM_len        = %i", mparm.COM_len);
		DEBUG("COM_data       = \"%s\"", mparm.COM_data);
		DEBUG("jpeg_markers   = %i", mparm.jpeg_markers);
		if(mparm.jpeg_markers & JPEG_MARKER_DHT) DEBUG("- DHT");
		if(mparm.jpeg_markers & JPEG_MARKER_DQT) DEBUG("- DQT");
		if(mparm.jpeg_markers & JPEG_MARKER_DRI) DEBUG("- DRI");
		if(mparm.jpeg_markers & JPEG_MARKER_COM) DEBUG("- COM");
		if(mparm.jpeg_markers & JPEG_MARKER_APP) DEBUG("- APP");
		DEBUG("VFIFO_FB       = %i", mparm.VFIFO_FB);
		
		/* Set the usual parameters. */
		mparm.input = 0;
		mparm.norm = VIDEO_MODE_PAL;
		/* TODO: Allow user to select PAL/SECAM/NTSC */
		
		mparm.decimation = 0;
		mparm.quality = 80;
		
		mparm.HorDcm = 1;
		mparm.VerDcm = 1;
		mparm.TmpDcm = 1;
		mparm.field_per_buff = 2;
		
		/* Ask the driver to include the DHT with each frame. */
		mparm.jpeg_markers |= JPEG_MARKER_DHT;
		
		if(ioctl(s->fd, MJPIOC_S_PARAMS, &mparm))
		{
			ERROR("Error setting video parameters.");
			ERROR("MJPIOC_S_PARAMS: %s", strerror(errno));
			return(-1);
		}
		
		src->width = mparm.img_width / mparm.HorDcm;
		src->height = mparm.img_height / mparm.VerDcm * mparm.field_per_buff;
		
		return(0);
	}
	
	v4l_pal = 2; /* Skip the JPEG palette. */
	
	if(src->palette != -1)
	{
		v4l_pal = 0;
		
		while(v4l_palette[v4l_pal].depth)
		{
			if(v4l_palette[v4l_pal].src == src->palette) break;
			v4l_pal++;
		}
		
		if(!v4l_palette[v4l_pal].depth)
		{
			ERROR("Unable to handle palette format %s.",
			      src_palette[src->palette]);
			
			return(-1);
		}
	}
	
	while(v4l_palette[v4l_pal].depth)
	{
		vp.palette = v4l_palette[v4l_pal].v4l;
		vp.depth   = v4l_palette[v4l_pal].depth;
		
		if(!ioctl(fd, VIDIOCSPICT, &vp))
		{
			s->palette = v4l_pal;
			src->palette = v4l_palette[v4l_pal].src;
			
			MSG("Using palette %s.",src_palette[src->palette].name);
			
			return(0);
		}
		
		if(src->palette != -1) break;
		
		WARN("The device does not support palette %s.",
		     src_palette[v4l_palette[v4l_pal].src].name);
		
		v4l_pal++;
	}
	
	ERROR("Unable to find a compatible palette.");
	
	return(-1);
}