美乐图科技IPC摄像头试玩儿

IPC详细参数如下:

  1. 闪烁控制:50HZ,60HZ
  2. 拍照格式:Bmp,jpg.
  3. 传感器格式:CMOS
  4. 支持Netmeeting等各种视频会议软件
  5. 180M/bmp告诉处理器
  6. 接口类型:USB2.0
  7. 内置:吸音降噪麦克风
  8. 分辨率:1920x1080/1280x720

USB描述符信息:

Descriptor:

caozilong@caozilong-Vostro-3268:~$ lsusb -d 0c45:64ab -v

Bus 001 Device 011: ID 0c45:64ab Microdia 
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.01
  bDeviceClass          239 Miscellaneous Device
  bDeviceSubClass         2 ?
  bDeviceProtocol         1 Interface Association
  bMaxPacketSize0        64
  idVendor           0x0c45 Microdia
  idProduct          0x64ab 
  bcdDevice           10.12
  iManufacturer           1 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          389
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Association:
      bLength                 8
      bDescriptorType        11
      bFirstInterface         0
      bInterfaceCount         2
      bFunctionClass         14 Video
      bFunctionSubClass       3 Video Interface Collection
      bFunctionProtocol       0 
      iFunction               4 
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      1 Video Control
      bInterfaceProtocol      0 
      iInterface              4 
      VideoControl Interface Descriptor:
        bLength                13
        bDescriptorType        36
        bDescriptorSubtype      1 (HEADER)
        bcdUVC               1.00
        wTotalLength          109
        dwClockFrequency       48.000000MHz
        bInCollection           1
        baInterfaceNr( 0)       1
      VideoControl Interface Descriptor:
        bLength                18
        bDescriptorType        36
        bDescriptorSubtype      2 (INPUT_TERMINAL)
        bTerminalID             1
        wTerminalType      0x0201 Camera Sensor
        bAssocTerminal          0
        iTerminal               0 
        wObjectiveFocalLengthMin      0
        wObjectiveFocalLengthMax      0
        wOcularFocalLength            0
        bControlSize                  3
        bmControls           0x0000000e
          Auto-Exposure Mode
          Auto-Exposure Priority
          Exposure Time (Absolute)
      VideoControl Interface Descriptor:
        bLength                11
        bDescriptorType        36
        bDescriptorSubtype      5 (PROCESSING_UNIT)
      Warning: Descriptor too short
        bUnitID                 2
        bSourceID               1
        wMaxMultiplier      16384
        bControlSize            2
        bmControls     0x0000177f
          Brightness
          Contrast
          Hue
          Saturation
          Sharpness
          Gamma
          White Balance Temperature
          Backlight Compensation
          Gain
          Power Line Frequency
          White Balance Temperature, Auto
        iProcessing             0 
        bmVideoStandards     0x1d
          None
          PAL - 625/50
          SECAM - 625/50
          NTSC - 625/50
      VideoControl Interface Descriptor:
        bLength                29
        bDescriptorType        36
        bDescriptorSubtype      6 (EXTENSION_UNIT)
        bUnitID                 3
        guidExtensionCode         {7033f028-1163-2e4a-ba2c-6890eb334016}
        bNumControl             4
        bNrPins                 1
        baSourceID( 0)          2
        bControlSize            4
        bmControls( 0)       0x0f
        bmControls( 1)       0x00
        bmControls( 2)       0x00
        bmControls( 3)       0x00
        iExtension              0 
      VideoControl Interface Descriptor:
        bLength                29
        bDescriptorType        36
        bDescriptorSubtype      6 (EXTENSION_UNIT)
        bUnitID                 4
        guidExtensionCode         {82066163-7050-ab49-b8cc-b3855e8d221d}
        bNumControl            20
        bNrPins                 1
        baSourceID( 0)          3
        bControlSize            4
        bmControls( 0)       0xff
        bmControls( 1)       0xff
        bmControls( 2)       0x71
        bmControls( 3)       0x00
        iExtension              0 
      VideoControl Interface Descriptor:
        bLength                 9
        bDescriptorType        36
        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
        bTerminalID             5
        wTerminalType      0x0101 USB Streaming
        bAssocTerminal          0
        bSourceID               4
        iTerminal               0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x87  EP 7 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               8
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           0
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      VideoStreaming Interface Descriptor:
        bLength                            15
        bDescriptorType                    36
        bDescriptorSubtype                  1 (INPUT_HEADER)
        bNumFormats                         2
        wTotalLength                      185
        bEndPointAddress                  129
        bmInfo                              0
        bTerminalLink                       5
        bStillCaptureMethod                 1
        bTriggerSupport                     1
        bTriggerUsage                       0
        bControlSize                        1
        bmaControls( 0)                    11
        bmaControls( 1)                    11
      VideoStreaming Interface Descriptor:
        bLength                            11
        bDescriptorType                    36
        bDescriptorSubtype                  6 (FORMAT_MJPEG)
        bFormatIndex                        1
        bNumFrameDescriptors                2
        bFlags                              1
          Fixed-size samples: Yes
        bDefaultFrameIndex                  1
        bAspectRatioX                       0
        bAspectRatioY                       0
        bmInterlaceFlags                 0x00
          Interlaced stream or variable: No
          Fields per frame: 1 fields
          Field 1 first: No
          Field pattern: Field 1 only
          bCopyProtect                      0
      VideoStreaming Interface Descriptor:
        bLength                            30
        bDescriptorType                    36
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        bFrameIndex                         1
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                           1280
        wHeight                           720
        dwMinBitRate                368640000
        dwMaxBitRate                368640000
        dwMaxVideoFrameBufferSize     1843200
        dwDefaultFrameInterval         400000
        bFrameIntervalType                  1
        dwFrameInterval( 0)            400000
      VideoStreaming Interface Descriptor:
        bLength                            30
        bDescriptorType                    36
        bDescriptorSubtype                  7 (FRAME_MJPEG)
        bFrameIndex                         2
        bmCapabilities                   0x00
          Still image unsupported
        wWidth                            640
        wHeight                           480
        dwMinBitRate                122880000
        dwMaxBitRate                122880000
        dwMaxVideoFrameBufferSize      614400
        dwDefaultFrameInterval         400000
        bFrameIntervalType                  1
        dwFrameInterval( 0)            400000
      VideoStreaming Interface Descriptor:
        bLength                             6
        bDescriptorType                    36
        bDescriptorSubtype                 13 (COLORFORMAT)
        bColorPrimaries                     1 (BT.709,sRGB)
        bTransferCharacteristics            1 (BT.709)
        bMatrixCoefficients                 4 (SMPTE 170M (BT.601))
      VideoStreaming Interface Descriptor:
        bLength                            27
        bDescriptorType                    36
        bDescriptorSubtype                  4 (FORMAT_UNCOMPRESSED)
        bFormatIndex                        2
        bNumFrameDescriptors                2
        guidFormat                            {59555932-0000-1000-8000-00aa00389b71}
        bBitsPerPixel                      16
        bDefaultFrameIndex                  1
        bAspectRatioX                       0
        bAspectRatioY                       0
        bmInterlaceFlags                 0x00
          Interlaced stream or variable: No
          Fields per frame: 2 fields
          Field 1 first: No
          Field pattern: Field 1 only
          bCopyProtect                      0
      VideoStreaming Interface Descriptor:
        bLength                            30
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         1
        bmCapabilities                   0x01
          Still image supported
        wWidth                           1280
        wHeight                           720
        dwMinBitRate                147456000
        dwMaxBitRate                147456000
        dwMaxVideoFrameBufferSize     1843200
        dwDefaultFrameInterval        1000000
        bFrameIntervalType                  1
        dwFrameInterval( 0)           1000000
      VideoStreaming Interface Descriptor:
        bLength                            30
        bDescriptorType                    36
        bDescriptorSubtype                  5 (FRAME_UNCOMPRESSED)
        bFrameIndex                         2
        bmCapabilities                   0x01
          Still image supported
        wWidth                            640
        wHeight                           480
        dwMinBitRate                 98304000
        dwMaxBitRate                 98304000
        dwMaxVideoFrameBufferSize      614400
        dwDefaultFrameInterval         500000
        bFrameIntervalType                  1
        dwFrameInterval( 0)            500000
      VideoStreaming Interface Descriptor:
        bLength                             6
        bDescriptorType                    36
        bDescriptorSubtype                 13 (COLORFORMAT)
        bColorPrimaries                     1 (BT.709,sRGB)
        bTransferCharacteristics            1 (BT.709)
        bMatrixCoefficients                 4 (SMPTE 170M (BT.601))
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x03fc  1x 1020 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x0bfc  2x 1020 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       3
      bNumEndpoints           1
      bInterfaceClass        14 Video
      bInterfaceSubClass      2 Video Streaming
      bInterfaceProtocol      0 
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            5
          Transfer Type            Isochronous
          Synch Type               Asynchronous
          Usage Type               Data
        wMaxPacketSize     0x13fc  3x 1020 bytes
        bInterval               1
caozilong@caozilong-Vostro-3268:~$ 

Camera支持信息:

#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h> 
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
 
#define CLEAR(x) memset(&(x), 0, sizeof(x))
char* dev_name;
int fd = -1;
int width = 640;
int height = 480;
FILE* f;
 
void errno_exit(const char *s)
{
	fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
	exit(-1);
}
 
int xioctl(int fh, int request, void *arg)
{
	int r;
 
	do {
		r = ioctl(fh, request, arg);
	} while (-1 == r && EINTR == errno);
 
	return r;
}
 
 
void close_device(void)
{
	if (-1 == close(fd))
		errno_exit("close");
 
	fd = -1;
}
 
void open_device(void)
{
	struct stat st;
	if (-1 == stat(dev_name, &st)) {
		fprintf(stderr, "Cannot identify '%s': %d, %s\n", dev_name, errno, strerror(errno));
		exit(-1);
	}
 
	if (!S_ISCHR(st.st_mode)) {
		fprintf(stderr, "%s is no devicen\n", dev_name);
		exit(-1);
	}
 
	fd = open(dev_name, O_RDWR | O_NONBLOCK, 0); // O_RDWR: required
	if (-1 == fd) {
		fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_name, errno, strerror(errno));
		exit(-1);
	}
}
 
void get_fmt(void)
{
	int ret;
	struct v4l2_fmtdesc fmt;
 
	memset(&fmt, 0, sizeof(fmt));
	fmt.index = 0;
	fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	while ((ret = ioctl(fd, VIDIOC_ENUM_FMT, &fmt)) == 0)
	{	
        	fmt.index++;
        	printf("{ pixelformat = ''%c%c%c%c'', description = ''%s'' }\n",
                 	 fmt.pixelformat & 0xFF, (fmt.pixelformat >> 8) & 0xFF, (fmt.pixelformat >> 16) & 0xFF,
                  	(fmt.pixelformat >> 24) & 0xFF, fmt.description);
	}
}
 
void get_input(void)
{
    struct v4l2_input inp;
    inp.index = 0;
    while (ioctl (fd, VIDIOC_ENUMINPUT, &inp) == 0) {
        printf("%s : std: 0x%llx\n", inp.name, inp.std);
        inp.index++;
    }
}
 
void set_input(void)
{
    struct v4l2_input inp;
    inp.index = 0;
    if (ioctl (fd, VIDIOC_S_INPUT, &inp) < 0) {
        printf("set input error.\n");
    }
}
 
void get_cap(void)
{
    struct v4l2_capability cap;
 
    if (ioctl(fd,VIDIOC_QUERYCAP,&cap) < 0)
    {
        printf("get cap error.\n");
        return;
    }
    else
    {
        printf("Driver Name:%s\nCard Name:%s\nBus info:%s\nDriver Version:%u.%u.%u\n",\
        cap.driver,cap.card,cap.bus_info,(cap.version>>16)&0XFF, (cap.version>>8)&0XFF,cap.version&0XFF); 
    }
 
	printf("Supported feature:\n");

	if(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
	{
            printf("    Video Capture.\n");
	}

	if(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)
	{
            printf("    Video Output.\n");
	}

	if(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
	{
            printf("    Capture MPlane.\n");
	}
 
	if(cap.capabilities & V4L2_CAP_STREAMING)
	{
            printf("    Streaming.\n");
	}
 
	if(cap.capabilities & V4L2_CAP_READWRITE)
	{
            printf("    readwrite.\n");
	}
 
	if(cap.capabilities & V4L2_CAP_DEVICE_CAPS)
	{
            printf("    device caps.\n");
	}
 
	if(cap.device_caps & V4L2_CAP_EXT_PIX_FORMAT)
	{
            printf("    ext pix format.\n");
	}

        return;
}
 
 
 
int main(void)
{
	// reference: https://linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/capture.c.html
	dev_name = "/dev/video0";
 
	open_device();
	get_fmt();
	get_input();
	set_input();
	get_cap();
	close_device();
 
	return 0;
}

get capability 结果如下:

czl@czl-RedmiBook-14:~/new$ ./a.out 
{ pixelformat = ''MJPG'', description = ''Motion-JPEG'' }
{ pixelformat = ''YUYV'', description = ''YUYV 4:2:2'' }
Camera 1 : std: 0x0
Driver Name:uvcvideo
Card Name:GENERAL WEBCAM: GENERAL WEBCAM
Bus info:usb-0000:00:14.0-1
Driver Version:4.15.18
Supported feature:
    Video Capture.
    Streaming.
    device caps.
    ext pix format.
czl@czl-RedmiBook-14:~/new$ 

获取分辨率信息:

void enum_picture_size(void) 
{
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    struct v4l2_fmtdesc fmt_1;
    struct v4l2_frmsizeenum frmsize;
    struct v4l2_frmivalenum frmival;

    fmt_1.index = 0;
    fmt_1.type = type;
    while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt_1) >= 0) {
        printf("{ pixelformat = ''%c%c%c%c'', description = ''%s'' }\n",
                 	 fmt_1.pixelformat & 0xFF, (fmt_1.pixelformat >> 8) & 0xFF, (fmt_1.pixelformat >> 16) & 0xFF,
                  	(fmt_1.pixelformat >> 24) & 0xFF, fmt_1.description);
        frmsize.pixel_format = fmt_1.pixelformat;
        frmsize.index = 0;
        while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) >= 0){
            if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){
                printf("    res: line:%d %dx%d\n",__LINE__, frmsize.discrete.width, frmsize.discrete.height);
            }else if(frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE){
                printf("    res: line:%d %dx%d\n",__LINE__, frmsize.discrete.width, frmsize.discrete.height);
            }
            frmsize.index++;
      }
      fmt_1.index++;
    }
}

输出如下:

 这和guvcview工具中显示的设置选项是一致的。

在摆弄摄像头的过程中一直有几个疑惑:

疑惑1.为何有两个video节点?

疑惑2.为何只有/dev/video0节点打开后可以正常抓图,而打开/dev/video1节点,在调用ioctl进行配置的时候会出现IOCTL 调用失败?内核返回-ENOTTY,报告针对设备的非法IOCTL调用。

问题1我已经找到问题答案了,在probe uvc设备的时候,根据uvc usb device的配置描述符,它有两个interface,在USB世界里,一个interface代表的是一个驱动功能。所以这里会出现两个设备节点。

那问题2是什么原因呢?为什么两个节点不对等呢?经过一番苦苦搜索,终于找到答案,其实从USB设备的描述符就可以看出来,两个interface是不对等的,一个代表设备流DMA的产生设备,另一个则是控制设备,并非是可以产生流的设备,反映在驱动中,两个设备是通过不同的路径调用进V4L2核心层的,一个是uvc_meta_register,另一个是uvc_register_video,不同的入口会传递给V4L2核心层不同的struct v4l2_file_operations和struct v4l2_ioctl_ops,进而决定了不同的功能。

[   41.085019] uvcvideo: Found UVC 1.00 device Integrated Camera (0c45:64ab)
[   41.103321] CPU: 3 PID: 31 Comm: kworker/3:0 Not tainted 5.4.129+ #22
[   41.103322] Hardware name: Dell Inc. Vostro 3268/0TJYKK, BIOS 1.11.1 12/11/2018
[   41.103325] Workqueue: usb_hub_wq hub_event
[   41.103326] Call Trace:
[   41.103330]  dump_stack+0x6d/0x8b
[   41.103334]  uvc_register_video_device+0x5d/0x1b0 [uvcvideo]
[   41.103335]  uvc_probe+0x25e8/0x2a10 [uvcvideo]
[   41.103337]  usb_probe_interface+0x149/0x300
[   41.103339]  ? uvc_register_video_device+0x1b0/0x1b0 [uvcvideo]
[   41.103340]  ? usb_probe_interface+0x149/0x300
[   41.103342]  really_probe+0xf5/0x440
[   41.103343]  driver_probe_device+0x11b/0x130
[   41.103344]  __device_attach_driver+0x7b/0xe0
[   41.103345]  ? driver_allows_async_probing+0x60/0x60
[   41.103347]  bus_for_each_drv+0x6e/0xb0
[   41.103348]  __device_attach+0xe4/0x160
[   41.103349]  device_initial_probe+0x13/0x20
[   41.103349]  bus_probe_device+0x92/0xa0
[   41.103351]  device_add+0x402/0x690
[   41.103352]  ? _cond_resched+0x19/0x40
[   41.103353]  usb_set_configuration+0x3fd/0x8f0
[   41.103355]  ? kernfs_activate+0x78/0x80
[   41.103357]  generic_probe+0x2e/0x80
[   41.103357]  usb_probe_device+0x31/0x70
[   41.103358]  really_probe+0xf5/0x440
[   41.103359]  driver_probe_device+0x11b/0x130
[   41.103360]  __device_attach_driver+0x7b/0xe0
[   41.103361]  ? driver_allows_async_probing+0x60/0x60
[   41.103362]  bus_for_each_drv+0x6e/0xb0
[   41.103363]  __device_attach+0xe4/0x160
[   41.103364]  device_initial_probe+0x13/0x20
[   41.103365]  bus_probe_device+0x92/0xa0
[   41.103366]  device_add+0x402/0x690
[   41.103368]  ? add_device_randomness+0x9d/0x1c0
[   41.103369]  usb_new_device+0x218/0x4a0
[   41.103370]  hub_event+0x11b1/0x1760
[   41.103373]  process_one_work+0x20f/0x400
[   41.103374]  worker_thread+0x34/0x410
[   41.103375]  kthread+0x121/0x140
[   41.103377]  ? process_one_work+0x400/0x400
[   41.103377]  ? kthread_park+0x90/0x90
[   41.103379]  ret_from_fork+0x35/0x40
[   41.103380] uvc_register_video_device line 2002, VFL_DIR_RX.
[   41.103382] name Integrated Camera: Integrated C.determine_valid_ioctls line 546, is_vid 1, isvbi 0, is_radio 0, issdr 0, istec0, is rx1, istx 0.
[   41.103383] determine_valid_ioctls line 710, valid sinput
[   41.103385] determine_valid_ioctls line 749, vdev=0x000000006ae2f85d, &vdev->valid_ioctls =0x00000000a6ac5245, ioctls=0xc0000f01c6f8335 ops=0x0000000024f130d9.
[   41.103464] CPU: 3 PID: 31 Comm: kworker/3:0 Not tainted 5.4.129+ #22
[   41.103465] Hardware name: Dell Inc. Vostro 3268/0TJYKK, BIOS 1.11.1 12/11/2018
[   41.103467] Workqueue: usb_hub_wq hub_event
[   41.103467] Call Trace:
[   41.103469]  dump_stack+0x6d/0x8b
[   41.103471]  uvc_register_video_device+0x5d/0x1b0 [uvcvideo]
[   41.103473]  uvc_meta_register+0x46/0x50 [uvcvideo]
[   41.103474]  uvc_probe+0x25f9/0x2a10 [uvcvideo]
[   41.103476]  usb_probe_interface+0x149/0x300
[   41.103478]  ? uvc_register_video_device+0x1b0/0x1b0 [uvcvideo]
[   41.103479]  ? usb_probe_interface+0x149/0x300
[   41.103480]  really_probe+0xf5/0x440
[   41.103481]  driver_probe_device+0x11b/0x130
[   41.103482]  __device_attach_driver+0x7b/0xe0
[   41.103482]  ? driver_allows_async_probing+0x60/0x60
[   41.103484]  bus_for_each_drv+0x6e/0xb0
[   41.103485]  __device_attach+0xe4/0x160
[   41.103486]  device_initial_probe+0x13/0x20
[   41.103487]  bus_probe_device+0x92/0xa0
[   41.103488]  device_add+0x402/0x690
[   41.103489]  ? _cond_resched+0x19/0x40
[   41.103490]  usb_set_configuration+0x3fd/0x8f0
[   41.103491]  ? kernfs_activate+0x78/0x80
[   41.103493]  generic_probe+0x2e/0x80
[   41.103494]  usb_probe_device+0x31/0x70
[   41.103495]  really_probe+0xf5/0x440
[   41.103496]  driver_probe_device+0x11b/0x130
[   41.103497]  __device_attach_driver+0x7b/0xe0
[   41.103513]  ? driver_allows_async_probing+0x60/0x60
[   41.103514]  bus_for_each_drv+0x6e/0xb0
[   41.103515]  __device_attach+0xe4/0x160
[   41.103516]  device_initial_probe+0x13/0x20
[   41.103516]  bus_probe_device+0x92/0xa0
[   41.103517]  device_add+0x402/0x690
[   41.103519]  ? add_device_randomness+0x9d/0x1c0
[   41.103520]  usb_new_device+0x218/0x4a0
[   41.103521]  hub_event+0x11b1/0x1760
[   41.103524]  process_one_work+0x20f/0x400
[   41.103525]  worker_thread+0x34/0x410
[   41.103526]  kthread+0x121/0x140
[   41.103527]  ? process_one_work+0x400/0x400
[   41.103528]  ? kthread_park+0x90/0x90
[   41.103529]  ret_from_fork+0x35/0x40
[   41.103530] uvc_register_video_device line 2002, VFL_DIR_RX.

测试1:既然/dev/video1不提供视频流服务,那么把它去掉,UVC还能工作吗?

编译后安装新的内核,发现确实只剩下VIDEO0节点了,这个时候UVC还工作吗?

 经过实际测试,只有/dev/video0一个设备节点的情况下,仍然是可以工作的,而且效果设置功能没有受到影响。

需要说明的是,如下的错误打印不是由于去掉/dev/video1节点导致的,存在两个节点的正常情况下也会有这些错误打印输出,错误和去掉video1节点无关。

GUVCVIEW: version 2.0.5
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
V4L2_CORE: (UVCIOC_CTRL_MAP) Error: 没有那个文件或目录
​

通过命令行方式获取摄像头支持信息,安装V4L2-CTL工具

v4l2-ctl 是一个ELF格式的可执行程序:

czl@czl-RedmiBook-14:sudo apt install v4l-utils
czl@czl-RedmiBook-14:~/Workspace/mjpg-streamer$ which v4l2-ctl 
/usr/bin/v4l2-ctl
czl@czl-RedmiBook-14:~/Workspace/mjpg-streamer$ file /usr/bin/v4l2-ctl 
/usr/bin/v4l2-ctl: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a3f7076c3c6c05c983aac57d3edddba24251b8c8, stripped
v4l2-ctl -d0 --list-formats-ext
caozilong@caozilong-Vostro-3268:~$ v4l2-ctl -d0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
		Size: Discrete 1280x720
			Interval: Discrete 0.040s (25.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.040s (25.000 fps)

	Index       : 1
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
		Size: Discrete 1280x720
			Interval: Discrete 0.100s (10.000 fps)
		Size: Discrete 640x480
			Interval: Discrete 0.050s (20.000 fps)

caozilong@caozilong-Vostro-3268:~$ 

过程中调用的IOCTL如下:

​caozilong@caozilong-Vostro-3268:~$ strace -e trace=openat,ioctl,open v4l2-ctl -d0 --list-formats-ext
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libv4l2.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/librt.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libv4lconvert.so.0", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libjpeg.so.8", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/dev/video0", O_RDWR) = 3
openat(AT_FDCWD, "/sys/dev/char/81:0/uevent", O_RDONLY) = 4
ioctl(3, VIDIOC_QUERYCAP, {driver="uvcvideo", card="Integrated Camera: Integrated C", bus_info="usb-0000:00:14.0-2", version=5.4.129, capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_META_CAPTURE, device_caps=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_EXT_PIX_FORMAT}) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0482c0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffe6d0483b0) = -1 EINVAL (Invalid argument)
ioctl: VIDIOC_ENUM_FMT
ioctl(3, VIDIOC_ENUM_FMT, {index=0, type=V4L2_BUF_TYPE_VIDEO_CAPTURE, flags=V4L2_FMT_FLAG_COMPRESSED, description="Motion-JPEG", pixelformat=v4l2_fourcc('M', 'J', 'P', 'G')}) = 0
	Index       : 0
	Type        : Video Capture
	Pixel Format: 'MJPG' (compressed)
	Name        : Motion-JPEG
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=0, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), type=V4L2_FRMSIZE_TYPE_DISCRETE, discrete={width=1280, height=720}}) = 0
		Size: Discrete 1280x720
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=0, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), width=1280, height=720, type=V4L2_FRMIVAL_TYPE_DISCRETE, discrete=1/25}) = 0
			Interval: Discrete 0.040s (25.000 fps)
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=1, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), width=1280, height=720}) = -1 EINVAL (Invalid argument)
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=1, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), type=V4L2_FRMSIZE_TYPE_DISCRETE, discrete={width=640, height=480}}) = 0
		Size: Discrete 640x480
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=0, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), width=640, height=480, type=V4L2_FRMIVAL_TYPE_DISCRETE, discrete=1/25}) = 0
			Interval: Discrete 0.040s (25.000 fps)
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=1, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G'), width=640, height=480}) = -1 EINVAL (Invalid argument)
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=2, pixel_format=v4l2_fourcc('M', 'J', 'P', 'G')}) = -1 EINVAL (Invalid argument)

ioctl(3, VIDIOC_ENUM_FMT, {index=1, type=V4L2_BUF_TYPE_VIDEO_CAPTURE, flags=0, description="YUYV 4:2:2", pixelformat=v4l2_fourcc('Y', 'U', 'Y', 'V')}) = 0
	Index       : 1
	Type        : Video Capture
	Pixel Format: 'YUYV'
	Name        : YUYV 4:2:2
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=0, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), type=V4L2_FRMSIZE_TYPE_DISCRETE, discrete={width=1280, height=720}}) = 0
		Size: Discrete 1280x720
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=0, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), width=1280, height=720, type=V4L2_FRMIVAL_TYPE_DISCRETE, discrete=1/10}) = 0
			Interval: Discrete 0.100s (10.000 fps)
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=1, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), width=1280, height=720}) = -1 EINVAL (Invalid argument)
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=1, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), type=V4L2_FRMSIZE_TYPE_DISCRETE, discrete={width=640, height=480}}) = 0
		Size: Discrete 640x480
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=0, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), width=640, height=480, type=V4L2_FRMIVAL_TYPE_DISCRETE, discrete=1/20}) = 0
			Interval: Discrete 0.050s (20.000 fps)
ioctl(3, VIDIOC_ENUM_FRAMEINTERVALS, {index=1, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V'), width=640, height=480}) = -1 EINVAL (Invalid argument)
ioctl(3, VIDIOC_ENUM_FRAMESIZES, {index=2, pixel_format=v4l2_fourcc('Y', 'U', 'Y', 'V')}) = -1 EINVAL (Invalid argument)

ioctl(3, VIDIOC_ENUM_FMT, {index=2, type=V4L2_BUF_TYPE_VIDEO_CAPTURE}) = -1 EINVAL (Invalid argument)
+++ exited with 0 +++
caozilong@caozilong-Vostro-3268:~$ 
czl@czl-RedmiBook-14:~/Workspace/mjpg-streamer$ v4l2-ctl -D -d /dev/video0
Driver Info (not using libv4l2):
	Driver name   : uvcvideo
	Card type     : GENERAL WEBCAM: GENERAL WEBCAM
	Bus info      : usb-0000:00:14.0-4
	Driver version: 5.4.119
	Capabilities  : 0x84A00001
		Video Capture
		Metadata Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps   : 0x04200001
		Video Capture
		Streaming
		Extended Pix Format
czl@czl-RedmiBook-14:~/Workspace/mjpg-streamer$ v4l2-ctl -D -d /dev/video1
Driver Info (not using libv4l2):
	Driver name   : uvcvideo
	Card type     : GENERAL WEBCAM: GENERAL WEBCAM
	Bus info      : usb-0000:00:14.0-4
	Driver version: 5.4.119
	Capabilities  : 0x84A00001
		Video Capture
		Metadata Capture
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps   : 0x04A00000
		Metadata Capture
		Streaming
		Extended Pix Format
czl@czl-RedmiBook-14:~/Workspace/mjpg-streamer$ 

根据上面v4l2-ctl获取到的信息,两个节点显然是不相同的,/dev/video1是Metadata Capture, /dev/video0是video capture.,以下是谷歌到的一段解释,看来某位国外小哥曾经和我有同样的疑惑. :)

The userspace app has to check the output of an ioctl (VIDIOC_QUERYCAP). It has two capability flags there at the returned struct:

struct v4l2_capability {
         ...
	__u32	capabilities;
	__u32	device_caps;
         ...
};

Those are documented as:

  * @capabilities: capabilities of the physical device as a whole
  * @device_caps:  capabilities accessed via this particular device (node)

In other words, applications need to check the device_caps, and not the capabilities. The two relevant caps here are:

   #define V4L2_CAP_VIDEO_CAPTURE		0x00000001 # bit 1
   #define V4L2_CAP_META_CAPTURE		0x00800000 # bit 23

/dev/video0 has:

   Device Caps   : 0x04200001

E.g. bit 1 is set, so this has V4L2_CAP_VIDEO_CAPTURE.

/dev/video1 has:

   Device Caps   : 0x04A00000

This one has bit 23 set (and bit 1 reset), so it doesn't have capture. It has, instead, meta capture.

The applications need to check this in order to know what kind of buffer it will receive, as this should be used by the streaming ioctls: VIDIOC_REQBUFS, VIDIOC_QBUF, VIDIOC_DQBUF, ...

If the application sets the buffer type correctly, it won't fail.

On other words, for /dev/video1, it has to use V4L2_BUF_TYPE_META_CAPTURE.

For /dev/video0, it has to use V4L2_BUF_TYPE_VIDEO_CAPTURE.

Please notice that what /dev/video1 will return is a meta-data image, with could be used by 3A algorithms to improve the image quality.

V4L2 read control menus:

czl@czl-RedmiBook-14:~$ strace -e trace=ioctl v4l2-ctl -L
ioctl(3, VIDIOC_QUERYCAP, {driver="uvcvideo", card="GENERAL WEBCAM: GENERAL WEBCAM", bus_info="usb-0000:00:14.0-4", version=5.4.119, capabilities=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_DEVICE_CAPS|V4L2_CAP_EXT_PIX_FORMAT|V4L2_CAP_META_CAPTURE, device_caps=V4L2_CAP_VIDEO_CAPTURE|V4L2_CAP_STREAMING|V4L2_CAP_EXT_PIX_FORMAT}) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe7800) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = -1 EINVAL (Invalid argument)
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_G_CTRL, {id=V4L2_CID_BRIGHTNESS, value=16}) = 0
                     brightness 0x00980900 (int)    : min=1 max=255 step=1 default=16 value=16
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_G_CTRL, {id=V4L2_CID_CONTRAST, value=16}) = 0
                       contrast 0x00980901 (int)    : min=1 max=255 step=1 default=16 value=16
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_G_CTRL, {id=V4L2_CID_HUE, value=16}) = 0
                            hue 0x00980903 (int)    : min=-128 max=127 step=1 default=16 value=16
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = 0
ioctl(3, VIDIOC_G_CTRL, {id=V4L2_CID_POWER_LINE_FREQUENCY, value=2}) = 0
           power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=2 value=2
ioctl(3, VIDIOC_QUERYMENU, 0x7ffc60fe77e0) = 0
				0: Disabled
ioctl(3, VIDIOC_QUERYMENU, 0x7ffc60fe77e0) = 0
				1: 50 Hz
ioctl(3, VIDIOC_QUERYMENU, 0x7ffc60fe77e0) = 0
				2: 60 Hz
ioctl(3, VIDIOC_QUERY_EXT_CTRL, 0x7ffc60fe78f0) = -1 EINVAL (Invalid argument)
+++ exited with 0 +++
czl@czl-RedmiBook-14:~$ 

AMCapSetup是另一款windows平台上的的摄像头工具,其界面如下所示:


另外,对于S_FMT的参数,要看设备的capability是否支持对应的功能,每一种功能对应一种结构的解释(union结构体),比如上图来说,Device Caps   : 0x04200001表示支持streaming, capture, and extent,不支持overlay,所以设置overlay就可能会失败。caputure摄像头都会支持,所以可以设置pix.


结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papaofdoudou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值