⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uvc_ctrl.c

📁 LINUXvideopPREVIEW, LINUX下面打开图像的工具源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *      uvcvideo.c  --  USB Video Class driver * *      Copyright (C) 2005-2006 *          Laurent Pinchart (laurent.pinchart@skynet.be) * *      This program is free software; you can redistribute it and/or modify *      it under the terms of the GNU General Public License as published by *      the Free Software Foundation; either version 2 of the License, or *      (at your option) any later version. * */#include <linux/kernel.h>#include <linux/version.h>#include <linux/list.h>#include <linux/module.h>#include <linux/usb.h>#include <linux/videodev.h>#include <linux/vmalloc.h>#include <linux/wait.h>#include <asm/atomic.h>#include "uvcvideo.h"#define UVC_CONTROL_SET_CUR	(1 << 0)#define UVC_CONTROL_GET_CUR	(1 << 1)#define UVC_CONTROL_GET_MIN	(1 << 2)#define UVC_CONTROL_GET_MAX	(1 << 3)#define UVC_CONTROL_GET_RES	(1 << 4)#define UVC_CONTROL_GET_DEF	(1 << 5)#define UVC_CONTROL_GET_RANGE	(UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \				 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \				 UVC_CONTROL_GET_DEF)#define UVC_CTRL_NDATA		2#define UVC_CTRL_DATA_CURRENT	0#define UVC_CTRL_DATA_BACKUP	1/* ------------------------------------------------------------------------ * Control, formats, ... */static struct uvc_control_info uvc_ctrls[] = {	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_BRIGHTNESS_CONTROL,		.index		= 0,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_CONTRAST_CONTROL,		.index		= 1,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_HUE_CONTROL,		.index		= 2,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_SATURATION_CONTROL,		.index		= 3,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_SHARPNESS_CONTROL,		.index		= 4,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_GAMMA_CONTROL,		.index		= 5,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_BACKLIGHT_COMPENSATION_CONTROL,		.index		= 8,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_GAIN_CONTROL,		.index		= 9,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_POWER_LINE_FREQUENCY_CONTROL,		.index		= 10,		.size		= 1,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_HUE_AUTO_CONTROL,		.index		= 11,		.size		= 1,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR				| UVC_CONTROL_GET_DEF,	},	{		.entity		= UVC_GUID_LOGITECH_MOTOR,		.selector	= LXU_MOTOR_PANTILT_RELATIVE_CONTROL,		.index		= 0,		.size		= 4,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_DEF,	},	{		.entity		= UVC_GUID_LOGITECH_MOTOR,		.selector	= LXU_MOTOR_PANTILT_RESET_CONTROL,		.index		= 1,		.size		= 1,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES				| UVC_CONTROL_GET_DEF,	},	{		.entity		= UVC_GUID_UVC_CAMERA,		.selector	= CT_AE_MODE_CONTROL,		.index		= 1,		.size		= 1,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR				| UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES,	},	{		.entity		= UVC_GUID_UVC_CAMERA,		.selector	= CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,		.index		= 3,		.size		= 4,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES				| UVC_CONTROL_GET_DEF,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,		.index		= 12,		.size		= 1,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR				| UVC_CONTROL_GET_DEF,	},	{		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,		.index		= 6,		.size		= 2,		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES				| UVC_CONTROL_GET_DEF,	}};static struct uvc_menu_info power_line_frequency_controls[] = {	{ 0, "Disabled" },	{ 1, "50 Hz" },	{ 2, "60 Hz" },};static struct uvc_control_mapping uvc_ctrl_mappings[] = {	{		.id		= V4L2_CID_BRIGHTNESS,		.name		= "Brightness",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_BRIGHTNESS_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_CONTRAST,		.name		= "Contrast",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_CONTRAST_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_HUE,		.name		= "Hue",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_HUE_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_SATURATION,		.name		= "Saturation",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_SATURATION_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_SHARPNESS,		.name		= "Sharpness",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_SHARPNESS_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_GAMMA,		.name		= "Gamma",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_GAMMA_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_BACKLIGHT_COMPENSATION,		.name		= "Backlight Compensation",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_BACKLIGHT_COMPENSATION_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_GAIN,		.name		= "Gain",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_GAIN_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_POWER_LINE_FREQUENCY,		.name		= "Power Line Frequency",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_POWER_LINE_FREQUENCY_CONTROL,		.size		= 2,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_MENU,		.data_type	= UVC_CTRL_DATA_TYPE_ENUM,		.menu_info	= power_line_frequency_controls,		.menu_count	= ARRAY_SIZE(power_line_frequency_controls),	},	{		.id		= V4L2_CID_HUE_AUTO,		.name		= "Hue, Auto",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_HUE_AUTO_CONTROL,		.size		= 1,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,		.data_type	= UVC_CTRL_DATA_TYPE_BOOLEAN,	},	{		.id		= V4L2_CID_PAN_RELATIVE,		.name		= "Pan (relative)",		.entity		= UVC_GUID_LOGITECH_MOTOR,		.selector	= LXU_MOTOR_PANTILT_RELATIVE_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_SIGNED,	},	{		.id		= V4L2_CID_TILT_RELATIVE,		.name		= "Tilt (relative)",		.entity		= UVC_GUID_LOGITECH_MOTOR,		.selector	= LXU_MOTOR_PANTILT_RELATIVE_CONTROL,		.size		= 16,		.offset		= 16,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_SIGNED,	},	{		.id		= V4L2_CID_PANTILT_RESET,		.name		= "Pan/Tilt (reset)",		.entity		= UVC_GUID_LOGITECH_MOTOR,		.selector	= LXU_MOTOR_PANTILT_RESET_CONTROL,		.size		= 2,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_ENUM,	},	{		.id		= V4L2_CID_EXPOSURE_AUTO,		.name		= "Exposure, Auto",		.entity		= UVC_GUID_UVC_CAMERA,		.selector	= CT_AE_MODE_CONTROL,		.size		= 4,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_BITMASK,	},	{		.id		= V4L2_CID_EXPOSURE_ABSOLUTE,		.name		= "Exposure (Absolute)",		.entity		= UVC_GUID_UVC_CAMERA,		.selector	= CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,		.size		= 32,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	},	{		.id		= V4L2_CID_WHITE_BALANCE_TEMPERATURE_AUTO,		.name		= "White Balance Temperature, Auto",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,		.size		= 1,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_BOOLEAN,		.data_type	= UVC_CTRL_DATA_TYPE_BOOLEAN,	},	{		.id		= V4L2_CID_WHITE_BALANCE_TEMPERATURE,		.name		= "White Balance Temperature",		.entity		= UVC_GUID_UVC_PROCESSING,		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,		.size		= 16,		.offset		= 0,		.v4l2_type	= V4L2_CTRL_TYPE_INTEGER,		.data_type	= UVC_CTRL_DATA_TYPE_UNSIGNED,	}};/* ------------------------------------------------------------------------ * Utility functions */static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id){	return ctrl->data + id * ctrl->info->size;}static inline int uvc_get_bit(const __u8 *data, int bit){	return (data[bit >> 3] >> (bit & 7)) & 1;}/* Extract the bit string specified by mapping->offset and mapping->size * from the little-endian data stored at 'data' and return the result as * a signed 32bit integer. Sign extension will be performed if the mapping * references a signed data type. */static __s32 uvc_get_le_value(const __u8 *data,	struct uvc_control_mapping *mapping){	int bits = mapping->size;	int offset = mapping->offset;	__s32 value = 0;	__u8 mask;	data += offset / 8;	offset &= 7;	mask = ((1 << bits) - 1) << offset;	for (; bits > 0; data++) {		__u8 byte = *data & mask;		value |= offset > 0 ? (byte >> offset) : (byte << (-offset));		bits -= 8 - (offset > 0 ? offset : 0);		offset -= 8;		mask = (1 << bits) - 1;	}	/* Sign-extend the value if needed */	if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED)		value |= -(value & (1 << (mapping->size - 1)));	return value;}/* Set the bit string specified by mapping->offset and mapping->size * in the little-endian data stored at 'data' to the value 'value'. */static void uvc_set_le_value(__s32 value, __u8 *data,	struct uvc_control_mapping *mapping){	int bits = mapping->size;	int offset = mapping->offset;	__u8 mask;	data += offset / 8;	offset &= 7;	for (; bits > 0; data++) {		mask = ((1 << bits) - 1) << offset;		*data = (*data & ~mask) | ((value << offset) & mask);		value >>= offset ? offset : 8;		bits -= 8 - offset;		offset = 0;	}}/* ------------------------------------------------------------------------ * Terminal and unit management */static const __u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;static const __u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]){	switch (entity->type) {	case ITT_CAMERA:		return memcmp(uvc_camera_guid, guid, 16) == 0;	case VC_PROCESSING_UNIT:		return memcmp(uvc_processing_guid, guid, 16) == 0;	case VC_EXTENSION_UNIT:		return memcmp(entity->extension.guidExtensionCode, guid, 16) == 0;	default:		return 0;	}}/* ------------------------------------------------------------------------ * UVC Controls */static struct uvc_control *__uvc_find_control(struct uvc_entity *entity,	__u32 v4l2_id, struct uvc_control_mapping **mapping){	struct uvc_control *ctrl;	struct uvc_control_mapping *map;	unsigned int i;	for (i = 0; i < entity->ncontrols; ++i) {		ctrl = &entity->controls[i];		if (ctrl->info == NULL)			continue;		list_for_each_entry(map, &ctrl->info->mappings, list) {			if (map->id == v4l2_id) {				*mapping = map;				return ctrl;			}		}	}	return NULL;}struct uvc_control *uvc_find_control(struct uvc_video_device *video,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -