#include "../imediadeviceinfo.h" #include #include #include #include #include #include #include //v4l includes #include #ifndef MAX_PATH #define MAX_PATH 260 #endif // !MAX_PATH int rvc_videocap_get_device_count() { int icount = 0; int fd = -1; for (int index = 0; index < 64; index++) { char device[MAX_PATH] = { 0 }; snprintf(device, MAX_PATH, "/dev/video%d", index); if (-1 != (fd = open(device, O_RDONLY)) ) { // query device capabilities struct v4l2_capability cap = {0}; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0){ close(fd); continue; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)){ continue; } if (cap.capabilities & V4L2_CAP_STREAMING) { } if (cap.capabilities & V4L2_CAP_READWRITE) { } /* 查询支持的格式 */ struct v4l2_fmtdesc tFmtDesc = {0}; int iPixelFormat = 0; tFmtDesc.index = 0; tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) { if (V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_MJPEG == tFmtDesc.pixelformat) { iPixelFormat = tFmtDesc.pixelformat; icount++; break; } tFmtDesc.index++; } } } return icount; } int rvc_videocap_get_device_name(int device_id, char* buf, int len) { int iret = -1; char device[MAX_PATH] = { 0 }; int fd = -1; snprintf(device, MAX_PATH, "/dev/video%d", device_id); if (-1 != (fd = open(device, O_RDONLY))) { // query device capabilities struct v4l2_capability cap = { 0 }; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0){ close(fd); return iret; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)){ return iret; } if (cap.capabilities & V4L2_CAP_STREAMING) { } if (cap.capabilities & V4L2_CAP_READWRITE) { } /* 查询支持的格式 */ struct v4l2_fmtdesc tFmtDesc = { 0 }; int iPixelFormat = 0; tFmtDesc.index = 0; tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) { if (V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_MJPEG == tFmtDesc.pixelformat){ iPixelFormat = tFmtDesc.pixelformat; break; } tFmtDesc.index++; } if (0 != iPixelFormat) { snprintf(buf, len, "%s%s%s", cap.card, ";", cap.bus_info); iret = 0; } } return iret; } int rvc_videocap_get_device_path(int device_id, char* buf, int len) { return 0; } int rvc_videocap_get_device_info(int device_id, char* namebuf, int namelen, char* pathbuf, int pathlen) { int iret = -1; char device[MAX_PATH] = { 0 }; int fd = -1; snprintf(device, MAX_PATH, "/dev/video%d", device_id); if (-1 != (fd = open(device, O_RDONLY))) { // query device capabilities struct v4l2_capability cap = { 0 }; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { close(fd); return iret; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { return iret; } if (cap.capabilities & V4L2_CAP_STREAMING) { } if (cap.capabilities & V4L2_CAP_READWRITE) { } /* 查询支持的格式 */ struct v4l2_fmtdesc tFmtDesc = { 0 }; int iPixelFormat = 0; tFmtDesc.index = 0; tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) { if (V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_RGB565 == tFmtDesc.pixelformat) { iPixelFormat = tFmtDesc.pixelformat; break; } tFmtDesc.index++; } if (0 != iPixelFormat) { snprintf(namebuf, namelen, "%s", cap.card); snprintf(pathbuf, pathlen, "%s", cap.bus_info); iret = 0; } } return iret; } static int bin2str(unsigned char* x, int xlen, char* str, int str_size) { static const char* hex2char = "0123456789ABCDEF"; int i, k = 0; if (str_size <= xlen * 2) return -1; for (i = 0; i < xlen; ++i) { int h = x[i] >> 4; int l = x[i] & 0xf; str[k++] = hex2char[h]; str[k++] = hex2char[l]; } str[k] = 0; return k; } int rvc_videocap_get_device_fullpathname(int device_id, char* fullnamebuf, int fulllen) { int iret = -1; char device[MAX_PATH] = { 0 }; int fd = -1; snprintf(device, MAX_PATH, "/dev/video%d", device_id); if (-1 != (fd = open(device, O_RDONLY))) { // query device capabilities struct v4l2_capability cap = { 0 }; if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) { close(fd); return iret; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { return iret; } if (cap.capabilities & V4L2_CAP_STREAMING) { } if (cap.capabilities & V4L2_CAP_READWRITE) { } /* 查询支持的格式 */ struct v4l2_fmtdesc tFmtDesc = { 0 }; int iPixelFormat = 0; tFmtDesc.index = 0; tFmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; while ((ioctl(fd, VIDIOC_ENUM_FMT, &tFmtDesc)) == 0) { if (V4L2_PIX_FMT_YUYV == tFmtDesc.pixelformat || V4L2_PIX_FMT_RGB565 == tFmtDesc.pixelformat) { iPixelFormat = tFmtDesc.pixelformat; break; } tFmtDesc.index++; } if (0 != iPixelFormat) { if (NULL != cap.bus_info && NULL != cap.card) { char strmd5[MAX_PATH] = { 0 }; snprintf(strmd5, MAX_PATH, "%s", cap.bus_info); unsigned char x[MD5_DIGESTSIZE]; md5_ctx_t ctx; md5_init(&ctx); md5(x, strmd5, strlen(strmd5)); bin2str(x, sizeof(x), strmd5, sizeof(strmd5)); snprintf(fullnamebuf, fulllen, "%s:%s", cap.card, strmd5); iret = 0; } } } return iret; } int rvc_videocap_get_video_device_id(const char* dev_name) { int iret = -1; if (NULL == dev_name){ return iret; } int icount = rvc_videocap_get_device_count(); int ifound = 0; for (int i = 0; i < 64 && ifound < icount; ++i) { char strfullname[2*MAX_PATH] = { 0 }; if (0 == rvc_videocap_get_device_fullpathname(i, strfullname, 2 * MAX_PATH)){ ifound++; printf("camera name is: %s\n", strfullname); printf(" dev name is: %s\n", dev_name); if (0 == strcasecmp(strfullname, dev_name)) { iret = i; } } } return iret; }