经过这几天的搜素及琢磨,终于知道linux的webcam是什么了。要实现一个gadget camera,需要应用层程序、驱动程序,以及host侧对应的gadget camera驱动。这三个部分,可以参考现有的做修改实现自己的usb webcam。
先分析下uvc-gadget.c,了解下整个框架流程,特别是怎么去处理图像数据、什么时候传输等。
一个应用程序,跟使用它一样,如有使用介绍,先看介绍
static void usage(const char *argv0)
{
fprintf(stderr, "Usage: %s [options]\n", argv0);
fprintf(stderr, "Available options are\n");
fprintf(stderr, " -bUse bulk mode\n");
fprintf(stderr, " -d deviceVideo device\n");
fprintf(stderr, " -hPrint this help screen and exit\n");
fprintf(stderr, " -i imageMJPEG image\n");
} -b 使用bulk模式,一开始我以为跟bulk端点有关。
-d gadget驱动在用户空间的节点,注意这里是device侧驱动的节点
-i MJPEG图片,JPG图片?
主函数:
int main(int argc, char *argv[])
{
char *device = "/dev/video0";
struct uvc_device *dev;
int bulk_mode = 0;
char *mjpeg_image = NULL;
fd_set fds;
int ret, opt;
while ((opt = getopt(argc, argv, "bd:hi:")) != -1) {
switch (opt) {
case 'b':
bulk_mode = 1;
break;
case 'd':
device = optarg;
break;
case 'h':
usage(argv[0]);
return 0;
case 'i':
mjpeg_image = optarg;
break;
default:
fprintf(stderr, "Invalid option '-%c'\n", opt);
usage(argv[0]);
return 1;
}
}
printf("[uvc_gadget]: open %s\n", device);
dev = uvc_open(device);
if (dev == NULL)
return 1;
printf("[uvc_gadget]: load %s\n", mjpeg_image);
image_load(dev, mjpeg_image);
dev->bulk = bulk_mode;
uvc_events_init(dev);
uvc_video_init(dev);
FD_ZERO(&fds);
FD_SET(dev->fd, &fds);
while (1) {
fd_set efds = fds;
fd_set wfds = fds;
ret = select(dev->fd + 1, NULL, &wfds, &efds, NULL);
if (FD_ISSET(dev->fd, &efds))
uvc_events_process(dev);
if (FD_ISSET(dev->fd, &wfds))
uvc_video_process(dev);
}
uvc_close(dev);
return 0;
} 默认使用/dev/video0,-b则bulk_mode=1,
uvc事件初始化、uvc video初始化,
然后循环处理uvc事件、uvc video。