video4linux--2

Video standards
当然世界上现在有多个视频标准,如NTSC和PAL,他们又细分为好多种,那么我们的设备输入/输出究竟支持什么样的标准呢?我们的当前在使用的输入和输出正在使用的是哪个标准呢?我们怎么设置我们的某个输入输出使用的标准呢?这都是有方法的。
 
(1)查询,我们的输入支持什么标准,首先就得找到当前的这个输入的index,然后查出它的属性,在其属性里面可以得到该输入所支持的标准, 将它所支持的各个标准与所有的标准的信息进行比较,就可以获知所支持的各个标准的属性。一个输入所支持的标准应该是一个集合,而这个集合是用bit与的方 式使用一个64位数字表示的。因此我们所查到的是一个数字。
  1. Example 1-5. Information about the current video standard
  2. v4l2_std_id std_id; //这个就是个64bit得数
  3. struct v4l2_standard standard;
  4. //VIDIOC_G_STD就是获得当前输入使用的standard,不过这里只是得到了该标准的id即flag,还没有得到其具体的属性信息,具体的属性信息要通过列举操作来得到。
  5. if (-1 == ioctl (fd, VIDIOC_G_STD, &std_id)) { //获得了当前输入使用的standard
  6.         /* Note when VIDIOC_ENUMSTD always returns EINVAL this
  7.            is no video device or it falls under the USB exception,
  8.            and VIDIOC_G_STD returning EINVAL is no error. */
  9.         perror ("VIDIOC_G_STD");
  10.         exit (EXIT_FAILURE);
  11. }
  1. memset (&standard, 0, sizeof (standard));
  2. standard.index = 0; //从第一个开始列举
  3. //VIDIOC_ENUMSTD用来列举所支持的所有的video标准的信息,不过要先给standard结构的index域制定一个数值,所列举的标准的信息属性包含在standard里面,如果我们所列举的标准和std_id有共同的bit,那么就意味着这个标准就是当前输入所使用的标准,这样我们就得到了当前输入使用的标准的属性信息
  4. while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) {
  5.         if (standard.id & std_id) {
  6.                printf ("Current video standard: %s/n", standard.name);
  7.                exit (EXIT_SUCCESS);
  8.         }
  9.         standard.index++;
  10. }
  11. /* EINVAL indicates the end of the enumeration, which cannot be
  12.    empty unless this device falls under the USB exception. */
  13. if (errno == EINVAL || standard.index == 0) {
  14.         perror ("VIDIOC_ENUMSTD");
  15.         exit (EXIT_FAILURE);
  16. }
  17.  
  18. Example 1-6. Listing the video standards supported by the current input
  19. struct v4l2_input input;
  20. struct v4l2_standard standard;
  21. memset (&input, 0, sizeof (input));
  22. //首先获得当前输入的index,注意只是index,要获得具体的信息,就的调用列举操作
  23. if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) {
  24.         perror ("VIDIOC_G_INPUT");
  25.         exit (EXIT_FAILURE);
  26. }
  27. //调用列举操作,获得input.index对应的输入的具体信息
  28. if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) {
  29.         perror ("VIDIOC_ENUM_INPUT");
  30.         exit (EXIT_FAILURE);
  31. }
  32. printf ("Current input %s supports:/n", input.name);
  33. memset (&standard, 0, sizeof (standard));
  34. standard.index = 0;
  35. //列举所有的所支持的standard,如果standard.id与当前input的input.std有共同的bit flag,意味着当前的输入支持这个standard,这样将所有驱动所支持的standard列举一个遍,就可以找到该输入所支持的所有standard了。
  36. while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) {
  37.         if (standard.id & input.std)
  38.                 printf ("%s/n", standard.name);
  39.         standard.index++;
  40. }
  41. /* EINVAL indicates the end of the enumeration, which cannot be
  42.    empty unless this device falls under the USB exception. */
  43. if (errno != EINVAL || standard.index == 0) {
  44.         perror ("VIDIOC_ENUMSTD");
  45.         exit (EXIT_FAILURE);
  46. }
  47. Example 1-7. Selecting a new video standard
  48. struct v4l2_input input;
  49. v4l2_std_id std_id;
  50. memset (&input, 0, sizeof (input));
  51. //获得当前input的index
  52. if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) {
  53.         perror ("VIDIOC_G_INPUT");
  54.         exit (EXIT_FAILURE);
  55. }
  56. //列举出下标为input.index的input的属性到input里
  57. if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) {
  58.         perror ("VIDIOC_ENUM_INPUT");
  59.         exit (EXIT_FAILURE);
  60. }
  61. //如果该input所支持的标准里不包含V4L2_STD_PAL_BG,就退出
  62. if (0 == (input.std & V4L2_STD_PAL_BG)) {
  63.         fprintf (stderr, "Oops. B/G PAL is not supported./n");
  64.         exit (EXIT_FAILURE);
  65. }
  66. /* Note this is also supposed to work when only B
  67.    or G/PAL is supported. */
  68. std_id = V4L2_STD_PAL_BG;
  69. //如果当前input支持V4L2_STD_PAL_BG,就将其设置为V4L2_STD_PAL_BG
  70. if (-1 == ioctl (fd, VIDIOC_S_STD, &std_id)) {
  71.         perror ("VIDIOC_S_STD");
  72.         exit (EXIT_FAILURE);

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章