文章目录
在一些视频直播画面中需要将USB摄像头的通道与视频画面的关系固定下来,什么意思呢?假如一个页面需要播放3路视频,分别对应3个USB摄像头,要将USB的通道序号与播放画面的3路视频一一对应,且每次播放时USB通道序号与画面对应关系保持不变。怎么做呢?下面记录一下我的做法。
产生问题的原因
在嵌入式设备中使用多路USB摄像头时,在/dev目录中会产生/dev/video0、/dev/video1等类似的设备节点;有些USB摄像头支持多种格式的数据输出,例如YUV、mpeg、H264等,因此单个USB摄像头可能被驱动程序创建多个设备节点,那么如何选择需要的设备节点呢?
将同一个USB摄像头连接到同一个USB接口,但是顺序不同,产生设备的节点序号也不相同,假设有3个USB接口,接口1如果先连接则设备节点为/dev/video0,如果最后连接设备节点为/dev/video2
如果仅仅使用设备节点的序号,将导致直播画面的在不同连接顺序时,播放不同摄像头的视频。
那么怎么解决这个问题呢?这就需要根据USB的通道号来确定当前通道下USB摄像头的设备节点。
根据USB通道确定设备节点
在/sys/class/video4linux/
目录下的文件可以确定USB通道与设备节点的之间的关系
在此目录下video0
节点描述的USB通道与设备节点之间的关系,video0 -> ../../devices/soc0/soc/2100000.aips-bus/2184200.usb/ci_hdrc.1/usb2/2-1/2-1.1/2-1.1:1.0/video4linux/video0
;
其中2-1.1/2-1.1:1.0
描述了USB的通道号,由于此文件是目录链接,因此可以进入video0
目录查看
其中
device
描述了USB通道序号,可以用读取链接的办法获取通道号,name
是USB摄像头的设备名称;可以根据此确定是否是应用连接的USB摄像头。
代码实现
#define MAX_USB_CHANNEL (4)
#define VIDEO4LINUX_PATH "/sys/class/video4linux"
#define CAMERA_PRODUCT1 "HD USB Camera" //可产生多种数据格式的摄像头
#define CAMERA_PRODUCT2 "SWT USB2.0 Camera"
camera_struct usbcamera[MAX_USB_CHANNEL];
#define USB_VIDEO_BUF_REQ_CNT 16
typedef struct camera_node
{
char id[16];
int ch;
//V4L2
char devname[16];
int fd;
struct v4l2_format fmt;
struct v4l2_streamparm parm;
struct v4l2_requestbuffers req;
struct buffer *buffers;
int n_buffers;
unsigned int width;
unsigned int height;
unsigned int bitrate;
unsigned int buf_head;
unsigned char buf[VIDEO_BUF_SIZE];
}camera_struct;
static char *xreadlink(const char *path)
{
static const int GROWBY = 80; /* how large we will grow strings by */
char *buf = NULL;
int bufsize = 0, readsize = 0;
do {
buf = realloc(buf, bufsize += GROWBY);
readsize = readlink(path, buf, bufsize); /* 1st try */
if (readsize == -1) {
free(buf);
return NULL;