V4L2文檔翻譯(三)

用戶控制


設備通常有一些用戶可設置的控制器,如亮度和飽和度等等一些會展示在圖形用戶界面的東西。但不同設備會有不同的可用設置,而且此外其可設置值範圍、默認值在不同設備上也不盡相同。控制ioctl提供創造一個良好用戶界面的信息和機制,這會讓這些控制器在任何設備上都能正確的工作。

所有控制器都需通過ID值進行訪問。V4L2定義了一些用於特殊目的的ID。驅動也可以使用V4L2CID_PRIVATE_BASE和更大的值聲明其自定義控制器。預定義的ID帶有前綴V4L2_CID,在Table 1.1. Control IDs中列出http://linuxtv.org/downloads/v4l-dvb-apis/control.html#control-id
這些ID用來查詢一個控制器的屬性、用來獲取或設定當前的設置值。

通常應用程序應當明確提出關於他們的目標的一些控制器。每個控制器的名字應該便於理解,如果目標不便理解,驅動開發者應該提供用戶文檔,用戶可用以涉入驅動或開發盤控制程序。預定義ID應介紹一點控制編程,如在通道切換期間使設備靜音。

當進行了視頻輸入輸出切換、調製器和調諧器切換、聲音輸入輸出切換後驅動也許會列舉出一些不同的控制。不同場景中有不同的默認值、當前值、步進值以及菜單項。擁有自定義ID的控制可以更改自己的名字和類型。控制值是被全局保存的,不會因爲切換而改變,甚至當設備打開或關閉時,比如一個調諧radio頻率改變,不再外部應用請求的情況下。因爲V4L2沒有事件機制,所以如果一個panel程序想和其他的panel程序合作的話,就需要有規律的獲取控制值來更新用戶接口。

附帶:色溫表(來自http://en.wikipedia.org/wiki/Color_temperature)

溫度 光源
1700K 火柴
1850K 燭光、日出、日落
2700-3300K 白熾燈
3000K 柔(暖)光燈、日光燈
3200K 畫室燈光
3350K 製作室燈光
4100-4150K 月光
5000K 水平的日光、管燈、冷光燈
5500-6000K 豎向日光,電子閃光
6200K 氙氣閃光燈
6500K 陰天
6500-10500K LCD CRT屏幕
15000-27000 清純的藍色極光

應用程序可以通過VIDIOC_QUERYCTRL和VIDIOC_QUERYMENU ioctl來列舉有效的控制,通過VIDIOC_G_CTRL和VIDIOC_S_CTRL來獲取和設置控制值。當設備擁有一個或以上的設置時,驅動必須聲明VIDIOC_QUERYCTRL、VIDIOC_G_CTRL、VIDIOC_S_CTRL。當有一個或以上的菜單類型控制時還必須其對應驅動還必須聲明VIDIOC_QUERYMENU。

例1.8 列舉所有控制

struct v4l2_queryctrl queryctrl;
struct v4l2_querymenu querymenu;

static void
enumerate_menu (void)
{
    printf ("  Menu items:\n");

    memset (&querymenu, 0, sizeof (querymenu));
    querymenu.id = queryctrl.id;

    for (querymenu.index = queryctrl.minimum;
         querymenu.index <= queryctrl.maximum;
          querymenu.index++) {
        if (0 == ioctl (fd, VIDIOC_QUERYMENU, &querymenu)) {
            printf ("  %s\n", querymenu.name);
        }
    }
}

memset (&queryctrl, 0, sizeof (queryctrl));

for (queryctrl.id = V4L2_CID_BASE;
     queryctrl.id < V4L2_CID_LASTP1;
     queryctrl.id++) {
    if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) {
        if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
            continue;

        printf ("Control %s\n", queryctrl.name);

        if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
            enumerate_menu ();
    } else {
        if (errno == EINVAL)
            continue;

        perror ("VIDIOC_QUERYCTRL");
        exit (EXIT_FAILURE);
    }
}

for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
     queryctrl.id++) {
    if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) {
        if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
            continue;

        printf ("Control %s\n", queryctrl.name);

        if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
            enumerate_menu ();
    } else {
        if (errno == EINVAL)
            break;

        perror ("VIDIOC_QUERYCTRL");
        exit (EXIT_FAILURE);
    }
}

例1.9 更改控制

struct v4l2_queryctrl queryctrl;
struct v4l2_control control;

memset (&queryctrl, 0, sizeof (queryctrl));
queryctrl.id = V4L2_CID_BRIGHTNESS;

if (-1 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) {
    if (errno != EINVAL) {
        perror ("VIDIOC_QUERYCTRL");
        exit (EXIT_FAILURE);
    } else {
        printf ("V4L2_CID_BRIGHTNESS is not supported\n");
    }
} else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
    printf ("V4L2_CID_BRIGHTNESS is not supported\n");
} else {
    memset (&control, 0, sizeof (control));
    control.id = V4L2_CID_BRIGHTNESS;
    control.value = queryctrl.default_value;

    if (-1 == ioctl (fd, VIDIOC_S_CTRL, &control)) {
        perror ("VIDIOC_S_CTRL");
        exit (EXIT_FAILURE);
    }
}

memset (&control, 0, sizeof (control));
control.id = V4L2_CID_CONTRAST;

if (0 == ioctl (fd, VIDIOC_G_CTRL, &control)) {
    control.value += 1;

    /* The driver may clamp the value or return ERANGE, ignored here */

    if (-1 == ioctl (fd, VIDIOC_S_CTRL, &control)
        && errno != ERANGE) {
        perror ("VIDIOC_S_CTRL");
        exit (EXIT_FAILURE);
    }
/* Ignore if V4L2_CID_CONTRAST is unsupported */
} else if (errno != EINVAL) {
    perror ("VIDIOC_G_CTRL");
    exit (EXIT_FAILURE);
}

control.id = V4L2_CID_AUDIO_MUTE;
control.value = TRUE; /* silence */

/* Errors ignored */
ioctl (fd, VIDIOC_S_CTRL, &control);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章