Video standards
当然世界上现在有多个视频标准,如NTSC和PAL,他们又细分为好多种,那么我们的设备输入/输出究竟支持什么样的标准呢?我们的当前在使用的输入和输出正在使用的是哪个标准呢?我们怎么设置我们的某个输入输出使用的标准呢?这都是有方法的。
(1)查询,我们的输入支持什么标准,首先就得找到当前的这个输入的index,然后查出它的属性,在其属性里面可以得到该输入所支持的标准,将它所支持的各个标准与所有的标准的信息进行比较,就可以获知所支持的各个标准的属性。一个输入所支持的标准应该是一个集合,而这个集合是用bit与的方式使用一个64位数字表示的。因此我们所查到的是一个数字。
Example 1-5. Information about the current video standard
std_id; //这个就是个64bit得数
struct standard;
//就是获得当前输入使用的standard,不过这里只是得到了该标准的id即flag,还没有得到其具体的属性信息,具体的属性信息要通过列举操作来得到。
if (-1 == ioctl (fd, , &std_id)) { //获得了当前输入使用的standard
/* Note when VIDIOC_ENUMSTD always returns EINVAL this
is no video device or it falls under the USB exception,
and VIDIOC_G_STD returning EINVAL is no error. */
perror ("VIDIOC_G_STD");
exit (EXIT_FAILURE);
}
memset (&standard, 0, sizeof (standard));
standard.index = 0; //从第一个开始列举
//用来列举所支持的所有的video标准的信息,不过要先给standard结构的index域制定一个数值,所列举的标准的信息属性包含在standard里面,如果我们所列举的标准和std_id有共同的bit,那么就意味着这个标准就是当前输入所使用的标准,这样我们就得到了当前输入使用的标准的属性信息
while (0 == ioctl (fd, , &standard)) {
if (standard.id & std_id) {
printf ("Current video standard: %s\n", standard.name);
exit (EXIT_SUCCESS);
}
standard.index++;
}
/* EINVAL indicates the end of the enumeration, which cannot be
empty unless this device falls under the USB exception. */
if (errno == EINVAL || standard.index == 0) {
perror ("VIDIOC_ENUMSTD");
exit (EXIT_FAILURE);
}Example 1-6. Listing the video standards supported by the current input
struct input; struct standard; memset (&input, 0, sizeof (input));//首先获得当前输入的index,注意只是index,要获得具体的信息,就的调用列举操作 if (-1 == ioctl (fd, , &input.index)) { perror ("VIDIOC_G_INPUT"); exit (EXIT_FAILURE); } //调用列举操作,获得input.index对应的输入的具体信息 if (-1 == ioctl (fd, , &input)) { perror ("VIDIOC_ENUM_INPUT"); exit (EXIT_FAILURE); } printf ("Current input %s supports:\n", input.name); memset (&standard, 0, sizeof (standard)); standard.index = 0; //列举所有的所支持的standard,如果standard.id与当前input的input.std有共同的bit flag,意味着当前的输入支持这个standard,这样将所有驱动所支持的standard列举一个遍,就可以找到该输入所支持的所有standard了。 while (0 == ioctl (fd, , &standard)) { if (standard.id & input.std) printf ("%s\n", standard.name); standard.index++; } /* EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception. */ if (errno != EINVAL || standard.index == 0) { perror ("VIDIOC_ENUMSTD"); exit (EXIT_FAILURE); }Example 1-7. Selecting a new video standard
struct input; std_id; memset (&input, 0, sizeof (input)); //获得当前input的index if (-1 == ioctl (fd, , &input.index)) { perror ("VIDIOC_G_INPUT"); exit (EXIT_FAILURE); } //列举出下标为input.index的input的属性到input里 if (-1 == ioctl (fd, , &input)) { perror ("VIDIOC_ENUM_INPUT"); exit (EXIT_FAILURE); } //如果该input所支持的标准里不包含V4L2_STD_PAL_BG,就退出 if (0 == (input.std & V4L2_STD_PAL_BG)) { fprintf (stderr, "Oops. B/G PAL is not supported.\n"); exit (EXIT_FAILURE); } /* Note this is also supposed to work when only B or G/PAL is supported. */ std_id = V4L2_STD_PAL_BG; //如果当前input支持V4L2_STD_PAL_BG,就将其设置为V4L2_STD_PAL_BG if (-1 == ioctl (fd, , &std_id)) { perror ("VIDIOC_S_STD"); exit (EXIT_FAILURE); }