V4L2访问摄像头扩展单元命令
2021-07-22
1754
0
我们可以通过IOCTL访问扩展单元,调用方法如下:
ioctl(fd, UVCIOC_CTRL_QUERY, struct uvc_xu_control_query *);
访问不同的扩展命令只需要修改uvc_xu_control_query 结构体里面内容即可。
uvc_xu_control_query 结构体如下:
struct uvc_xu_control_query {
__u8 unit;//扩展单元ID
__u8 selector;//扩展命令ID
__u8 query;//特定类请求,如UVC_GET_CUR,定义在linux/usb/video.h
__u16 size;//命令数据长度
__u8 *data;//数据buf
};
假如我们访问失败,可能有以下几个原因:
1.扩展描述符中没有打开该命令,扩展单元协议可参照http://www.usbzh.com/article/detail-36.html 。
2.该扩展命令不支持GET_INFO或者GET_LEN
3.该扩展命令支持GET_LEN,但是返回的长度和我们定义的长度不一致
在开发过程中还遇到通过libuvc能够调用成功,但是v4l2调用失败,这是因为libuvc并不是严格按照UVC协议。
写了段示例代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <linux/uvcvideo.h>
#include <linux/usb/video.h>
#include <errno.h>
#include <string.h>
#define UVC_EU1_ID 0x06
#define EU1_TEST_CMD 0x3b
#define EU1_TEST_CMD_LEN 0x01
int main(int argc,char **argv){
int fd = open("/dev/video0",O_RDWR);
if(fd <= 0)
{
printf("open failed!\n");
return -1;
}
unsigned char buf[EU1_TEST_CMD_LEN];
struct uvc_xu_control_query xu_ctrl_query =
{
.unit = UVC_EU1_ID,
.selector = EU1_TEST_CMD,
.query = UVC_GET_CUR,
.size = EU1_TEST_CMD_LEN,
.data = buf,
};
int ret = ioctl(fd, UVCIOC_CTRL_QUERY, &xu_ctrl_query);
if(ret < 0)
{
printf("query fail!\n");
printf("%s\n",strerror(errno));
}else{
printf("query success!\n");
int i;
printf("data:");
for(i = 0;i < EU1_TEST_CMD_LEN;i++)
{
printf("%#x ",buf[i]);
}
printf("\n");
}
close(fd);
return 0;
}
HID人机交互QQ群:564808376
UAC音频QQ群:218581009
UVC相机QQ群:331552032
BOT&UASP大容量存储QQ群:258159197
STC-USB单片机QQ群:315457461
USB技术交流QQ群2:580684376
USB技术交流QQ群:952873936