video设备 支持功能查询 小工具,
方便v4l2开发
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <sys/mman.h>
#include <assert.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#define CLEAR(x) memset(&(x), 0, sizeof(x))
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
typedef long LONG;
#define CHECKNUM 8
struct {
unsigned int type;
char *name;
} enum_fmt[]={
{V4L2_CAP_VIDEO_CAPTURE, "V4L2_CAP_VIDEO_CAPTURE"},
{V4L2_CAP_VIDEO_OUTPUT, "V4L2_CAP_VIDEO_OUTPUT"},
{V4L2_CAP_VIDEO_OVERLAY, "V4L2_CAP_VIDEO_OVERLAY"},
{V4L2_CAP_VIDEO_CAPTURE_MPLANE, "V4L2_CAP_VIDEO_CAPTURE_MPLANE"},
{V4L2_CAP_VIDEO_OUTPUT_MPLANE, "V4L2_CAP_VIDEO_OUTPUT_MPLANE"},
{V4L2_CAP_VIDEO_M2M_MPLANE, "V4L2_CAP_VIDEO_M2M_MPLANE"},
{V4L2_CAP_VIDEO_M2M, "V4L2_CAP_VIDEO_M2M"},
{V4L2_CAP_STREAMING, "V4L2_CAP_STREAMING"},
};
int open_camer_device(char *path)
{
int fd;
if((fd = open(path,O_RDWR | O_NONBLOCK)) < 0)
{
perror("Fail to open");
exit(EXIT_FAILURE);
}
printf("open cam:%s success %d\n",path, fd);
return fd;
}
void enum_video_ctrls_and_menus(int fd){
/*
\* To query the attributes of a control applications set the id field of a struct
\* v4l2_queryctrl and call the VIDIOC_QUERYCTRL ioctl with a pointer to this
\* structure. The driver fills the rest of the structure or returns an EINVAL
\* error code when the id is invalid.
\*
\* To enumerate controls call VIDIOC_QUERYCTRL with successive
\* id values starting from V4L2_CID_BASE up to and exclusive V4L2_CID_LASTP1,
\* or starting from V4L2_CID_PRIVATE_BASE until the driver returns EINVAL.
*/
struct v4l2_queryctrl queryctrl; /* Query Control structure as defined in <sys/videodev2.h> */
struct v4l2_querymenu querymenu; /* Query Menu Structure as defined in <sys/videodev2.h> */
fprintf(stdout,"Discovering controls:\n");
memset (&queryctrl, 0, sizeof (queryctrl));
for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1; queryctrl.id++) {
if ( ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl) == 0 ) {
/* Check to see if this control is permanently disabled and should be ignored by the application */
if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
continue;
/* We got a video control back */
fprintf(stdout,"\nVIDIOC_QUERYCTRL(V4L2_CID_BASE+%d)\n", queryctrl.id-V4L2_CID_BASE);
fprintf(stdout," id: %d\n", queryctrl.id);
switch (queryctrl.type){
case V4L2_CTRL_TYPE_INTEGER:
fprintf(stdout, " type: INTEGER\n");
break;
case V4L2_CTRL_TYPE_BOOLEAN:
fprintf(stdout, " type: BOOLEAN\n");
break;
case V4L2_CTRL_TYPE_MENU:
fprintf(stdout, " type: MENU\n");
/* Additional information is required for menu controls, the name of menu items.
\* To query them applications set the id and index fields of struct v4l2_querymenu
\* and call the VIDIOC_QUERYMENU ioctl with a pointer to this structure. The driver
\* fills the rest of the structure or returns an EINVAL error code when the id or
\* index is invalid. Menu items are enumerated by calling VIDIOC_QUERYMENU with
\* successive index values from struct v4l2_queryctrl minimum (0) to maximum, inclusive.
*/
querymenu.id = queryctrl.id;
for (querymenu.index = queryctrl.minimum; querymenu.index < queryctrl.maximum; querymenu.index++){
fprintf(stdout, " menu id:%d\n", querymenu.index);
fprintf(stdout, " menu name:%s\n", querymenu.name);
}
break;
case V4L2_CTRL_TYPE_BUTTON:
fprintf(stdout, " type: BUTTON\n");
break;
}
fprintf(stdout," name: %s\n", queryctrl.name);
fprintf(stdout," minimum: %d\n", queryctrl.minimum);
fprintf(stdout," maximum: %d\n", queryctrl.maximum);
fprintf(stdout," step: %d\n", queryctrl.step);
fprintf(stdout," default_value: %d\n", queryctrl.default_value);
fprintf(stdout," flags: %d\n", queryctrl.flags);
} else {
if (errno == EINVAL)
continue;
perror("VIDIOC_QUERYCTRL");
break;
}
}
} /* End of enum_video_ctrls_and_menus() */
int main(int argc, char** argv)
{
int fd;
struct v4l2_fmtdesc fmt;
struct v4l2_capability cap;
struct v4l2_format stream_fmt;
struct v4l2_input input;
struct v4l2_control ctrl;
struct v4l2_streamparm stream;
int err;
int ret;
int i;
if (argc < 2) {
// printusage(argv[0]);
printf("please input path\n");
return -1;
}
fd = open_camer_device(argv[1]);
for(i = 0; i < CHECKNUM; i++)
{
memset(&fmt,0,sizeof(fmt));
fmt.index = 0;
fmt.type = enum_fmt[i].type;
//printf("enum_fmt:%s\n", enum_fmt[i].name);
while((ret = ioctl(fd,VIDIOC_ENUM_FMT,&fmt)) == 0)
{
fmt.index ++ ;
printf("%s:{pixelformat = %c%c%c%c},description = '%s'\n",
enum_fmt[i].name,
fmt.pixelformat & 0xff,(fmt.pixelformat >> 8)&0xff,
(fmt.pixelformat >> 16) & 0xff,(fmt.pixelformat >> 24)&0xff,
fmt.description);
}
}
printf("\n\n");
enum_video_ctrls_and_menus(fd);
//查询视频设备支持的功能
ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
if(ret < 0){
perror("FAIL to ioctl VIDIOC_QUERYCAP");
//exit(EXIT_FAILURE);
}
//printf("capabilities:%08x\n", cap.capabilities);
printf("\ncheck the support capabilities\n");
for(i = 0; i < CHECKNUM; i++)
{
if(cap.capabilities & enum_fmt[i].type)
printf("%s\n",enum_fmt[i].name);
}
printf("\n");
if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{
printf("The Current device is not a video capture device\n");
//exit(EXIT_FAILURE);
}
else
printf("The Current device is a video capture device\n");
if(!(cap.capabilities & V4L2_CAP_STREAMING))
{
printf("The Current device does not support streaming i/o\n");
//exit(EXIT_FAILURE);
}
else
printf("The Current device support streaming i/o\n");
return 0;
}
比如MFC设备
[liujia@210]#./cam_scan /dev/video9
open cam:/dev/video9 success 3
V4L2_CAP_VIDEO_CAPTURE:{pixelformat = H264},description = 'H264 Encoded Stream'
V4L2_CAP_VIDEO_CAPTURE:{pixelformat = MPG4},description = 'MPEG4 Encoded Stream'
V4L2_CAP_VIDEO_CAPTURE:{pixelformat = H263},description = 'H263 Encoded Stream'
Discovering controls:
check the support capabilities
V4L2_CAP_VIDEO_CAPTURE_MPLANE
V4L2_CAP_VIDEO_OUTPUT_MPLANE
V4L2_CAP_VIDEO_M2M_MPLANE
V4L2_CAP_STREAMING
The Current device is not a video capture device
The Current device support streaming i/o
USB camera设备
[liujia@210]#./cam_scan /dev/video13
open cam:/dev/video13 success 3
V4L2_CAP_VIDEO_CAPTURE:{pixelformat = YUYV},description = 'YUV 4:2:2 (YUYV)'
V4L2_CAP_VIDEO_CAPTURE:{pixelformat = MJPG},description = 'MJPEG'
Discovering controls:
VIDIOC_QUERYCTRL(V4L2_CID_BASE+0)
id: 9963776
type: INTEGER
name: Brightness
minimum: 0
maximum: 255
step: 1
default_value: 128
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+1)
id: 9963777
type: INTEGER
name: Contrast
minimum: 0
maximum: 255
step: 1
default_value: 32
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+2)
id: 9963778
type: INTEGER
name: Saturation
minimum: 0
maximum: 255
step: 1
default_value: 32
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+12)
id: 9963788
type: BOOLEAN
name: White Balance Temperature, Auto
minimum: 0
maximum: 1
step: 1
default_value: 1
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+19)
id: 9963795
type: INTEGER
name: Gain
minimum: 0
maximum: 255
step: 1
default_value: 0
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+24)
id: 9963800
type: MENU
menu id:0
menu name:rÿ¶DRï¶Ä
menu id:1
menu name:rÿ¶DRï¶Ä
name: Power Line Frequency
minimum: 0
maximum: 2
step: 1
default_value: 2
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+26)
id: 9963802
type: INTEGER
name: White Balance Temperature
minimum: 0
maximum: 10000
step: 10
default_value: 4000
flags: 16
VIDIOC_QUERYCTRL(V4L2_CID_BASE+27)
id: 9963803
type: INTEGER
name: Sharpness
minimum: 0
maximum: 255
step: 1
default_value: 24
flags: 0
VIDIOC_QUERYCTRL(V4L2_CID_BASE+28)
id: 9963804
type: INTEGER
name: Backlight Compensation
minimum: 0
maximum: 1
step: 1
default_value: 1
flags: 0
check the support capabilities
V4L2_CAP_VIDEO_CAPTURE
V4L2_CAP_STREAMING
The Current device is a video capture device
The Current device support streaming i/o