Поддержка драйвера для ориентации камеры

Это важно

Метод автокоррекции, рассмотренный далее в этом разделе, является рекомендуемым решением для установки датчиков камеры без ориентировки на эталон. Это необходимо для обеспечения совместимости приложений, так как большинство приложений, уже написанных для работы с потоками с камер, не умеет проверять или исправлять информацию о повороте изображения. Внимательно просмотрите информацию в разделе автокоррекции ниже.

По мере внедрения различных форм-факторов вычислительных устройств некоторые из физических ограничений приводят к тому, что датчики камеры устанавливаются в нестандартную ориентацию. Из-за этого необходимо правильно описать для ОС и приложений, как установлены датчики, чтобы итоговое видео можно было корректно отображать и записывать.

Начиная с Окна 10 версии 1607 все драйверы камеры должны явно указывать ориентацию камеры независимо от того, подключена ли камера в соответствии с минимальными требованиями к оборудованию. В частности, драйвер камеры должен задать только что введенное поле, поворот в структуре ACPI _PLD, связанной с интерфейсом устройства захвата:

typedef struct _ACPI_PLD_V2_BUFFER {

    UINT32 Revision:7;
    UINT32 IgnoreColor:1;
    UINT32 Color:24;
    // …
    UINT32 Panel:3;         // Already supported by camera.
    // …
    UINT32 CardCageNumber:8;
    UINT32 Reference:1;
    UINT32 Rotation:4;      // 0 – Rotate by 0° clockwise
                            // 1 – Rotate by 45° clockwise (N/A to camera)
                            // 2 – Rotate by 90° clockwise
                            // 3 – Rotate by 135° clockwise (N/A to camera)
                            // 4 – Rotate by 180° clockwise
                            // 5 – Rotate by 225° clockwise (N/A to camera)
                            // 6 – Rotate by 270° clockwise
    UINT32 Order:5;
    UINT32 Reserved:4;

    //
    // _PLD v2 definition fields.
    //

    USHORT VerticalOffset;
    USHORT HorizontalOffset;
} ACPI_PLD_V2_BUFFER, *PACPI_PLD_V2_BUFFER;

Для камеры поле поворота в структуре ACPI _PLD указывает количество градусов ("0" для 0°, "2" для 90°, "4" для 180°, а "6" для 270°) захваченный кадр поворачивается относительно экрана, пока дисплей находится в собственной ориентации.

В зависимости от значения в поле Rotation приложение может выполнять дополнительное вращение, при необходимости, чтобы правильно воспроизводить захваченные кадры.

Значения поворота

Для устройств, камеры и экраны которых размещены в одном и том же корпусе (или корпусе/оболочке), возможно установить эти периферийные устройства на различных поверхностях, при этом каждое из них может быть повернуто на фиксированный, но произвольный угол в своей плоскости. Следовательно, приложению требуется механизм для описания пространственной связи между двумя периферийными устройствами, таким образом, что захваченный кадр можно транспонировать на область отрисовки в правильной ориентации.

Одним из способов решения проблемы является использование структуры ACPI _PLD, которая уже имеет понятия поверхности и степени поворота . Например, _PLD структура уже имеет поле панели , указывающее поверхность, на которой находится периферийное устройство:

Поле для панели PLD ACPI.

Определение поля панели ACPI _PLD (ред. 5.0a)

На следующих двух схемах показано визуальное определение каждой панели:

Определения панелей для настольных компьютеров и большинства устройств

Определения панелей — рабочий стол.

Определения панелей для свертываемых устройств

Определения панелей — свертываемые устройства.

На самом деле, концепция ACPI "панель" уже используется в Windows, где:

  • Интерфейс устройства камеры связан со структурой _PLD, при этом поле Панели устанавливается соответствующим образом, если устройство захвата статически закреплено в фиксированном расположении.

  • Приложение может получить панель, на которой находится устройство записи, вызвав свойство Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .

Структура ACPI _PLD также имеет поле поворота, определенное следующим образом:

Определение поля поворота _PLD ACPI (ред. 5.0a)

Определения полей ACPI _PLD для поворота.

Вместо использования приведенного выше определения мы дополнительно уточняем его, чтобы избежать неоднозначности:

  • Для камеры поле поворота в структуре ACPI _PLD указывает количество градусов ("0" для 0°, "2" для 90°, "4" для 180°, а "6" для 270°) захваченный кадр поворачивается относительно экрана, пока дисплей находится в собственной ориентации.

Основная альбомная ориентация vs основная портретная ориентация

В Windows можно запрашивать собственную ориентацию отображения, вызвав свойство Windows.Graphics.Display.DisplayInformation.NativeOrientation, которое возвращает альбомную ориентацию или портретную ориентацию.

Отображение шаблона сканирования родной ориентации.

Независимо от того, какое значение возвращает NativeOrientation , шаблон проверки логического отображения начинается с левого верхнего угла дисплея, перемещающегося слева направо вниз (см. рис. 5). Для таких устройств, для которых физическая ориентация по умолчанию является неявной, это свойство не только подразумевает расположение верхней панели ACPI, но и определяет пространственное отношение между буфером вывода камеры и поверхностью отрисовки.

Обратите внимание, что, в отличие от камеры, свойство NativeOrientation не основано на ACPI и поэтому не имеет _PLD структуры. Это верно, даже если дисплей статически подключен к устройству.

При подключении к устройству с портретной ориентацией, драйверы камеры должны учитывать, что большинство приложений будет обрабатывать устройство как вывод буфера камеры в альбомной ориентации, независимо от фактической ориентации выходного буфера камеры. Из-за этого мы рекомендуем, чтобы драйверы камеры выводили буфер камеры со смещением ориентации на 90 градусов от ориентации по умолчанию (портрет) на устройстве с основным портретным режимом. Затем это позволит приложениям, выполняющим этот дополнительный поворот на портретных устройствах, скорректировать поворот до нужной ориентации. Это можно проверить с помощью приложения камеры с примером поворота.

Подключение смещения

IHV/OEM настоятельно рекомендуется избегать установки датчика с углом наклона, отличающимся от нуля, чтобы обеспечить совместимость приложения. Многие существующие и устаревшие приложения не знают, как искать таблицу PLD ACPI и не будут пытаться исправить смещение, несоответствующее 0 градусам. Следовательно, для таких приложений результирующее видео будет отображаться неправильно.

В случаях, когда IHV/OEM не удается подключить датчик в ориентации на 0 градусов, как описано выше, рекомендуется выполнить следующие действия по устранению рисков в порядке предпочтения:

  1. Автоматическое исправление ориентации, отличной от 0 градусов, в драйвере камеры (в режиме ядра с драйвером минипорта AV или в пользовательском режиме с помощью подключаемого модуля, например Device MFT или MFT0), чтобы полученные выходные кадры были в ориентации на 0 градусов.

  2. Укажите ненулевую ориентацию с помощью тега FSSensorOrientation, чтобы конвейер камеры смог исправить захваченное изображение.

  3. Задайте ориентацию, отличную от 0 градусов, в таблице PLD ACPI, как описано выше.

Сжатые или кодированные типы носителей

Для сжатых и /или кодированных типов мультимедиа (например, MJPG, JPEG, H264, HEVC) невозможно использовать правильный конвейер. Из-за этого сжатые или закодированные типы мультимедиа будут отфильтрованы, если FSSensorOrientation имеет ненулевое значение.

В случае типов мультимедиа MJPG (например, с камеры UVC) конвейер сервера кадров предоставляет автоматически декодированные типы мультимедиа (NV12 или YUY2 для приложений на основе DShow). Будет представлен автоматически декодированный и исправленный тип носителя, но исходный формат MJPG представлен не будет.

[! ПРИМЕЧАНИЕ!] Если сжатые или кодированные типы мультимедиа должны быть предоставлены приложениям, IHV/ODMS не должны использовать исправление FSSensorOrientation. Вместо этого необходимо выполнить исправление драйвером камеры (в режиме ядра через драйвер AV Stream или в пользовательском режиме через DMFT/MFT0).

Автокоррекция через AV Stream Miniport/Device MFT/MFT0

Рекомендуемый сценарий, если датчики не могут быть установлены с углом смещения 0 градусов, заключается в том, что драйвер минипорта AV Stream (или подключаемые модули пользовательского режима в виде DMFT или MFT0) должны исправить полученный захваченный кадр, чтобы он был представлен конвейеру с углом смещения 0 градусов.

При исправлении видеокадры из минипорта AV Stream и (или) подключаемого модуля Device MFT/MFT0 итоговая объявление типа носителя должна основываться на исправленном кадре. Если датчик установлен с смещением на 90 градусов, то видео автоматически получается с соотношением сторон 9:16, но исправленное видео будет с соотношением сторон 16:9. Тип носителя должен указывать соотношение сторон 16:9.

Сюда входят полученные параметры шага. Это необходимо, поскольку компонент, ответственный за осуществление корректировки, контролируется IHV/OEM, и процесс обработки камеры не имеет доступа к видеофрейму до его коррекции.

Настоятельно рекомендуется выполнять исправление в пользовательском режиме. Контракт API между пайплайном и подключаемым модулем пользовательского режима должен соблюдаться. В частности, при использовании либо DMFT, либо MFT0, когда метод IMFDeviceTransform::ProcessMessage или IMFTransform::ProcessMessage вызывается с сообщением MFT_MESSAGE_SET_D3D_MANAGER, подключаемый модуль пользовательского режима должен следовать следующему руководству:

  • Если диспетчер D3D не указан (ulParam сообщения равен 0), подключаемый модуль в пользовательском режиме не должен запускать никаких операций GPU для выполнения коррекции поворота. И результирующий кадр должен быть предоставлен в системной памяти.
  • Если передан диспетчер D3D (ulParam сообщения является IUnknown диспетчера DXGI), этот диспетчер DXGI должен использоваться для коррекции поворота, а результирующий кадр должен находиться в видеопамяти GPU.
  • Подключаемый модуль пользовательского режима также должен обрабатывать сообщение диспетчера D3D во время выполнения. При выпуске сообщения MFT_MESSAGE_SET_D3D_MANAGER следующий кадр, созданный подключаемым модулем, должен соответствовать запрошенному типу памяти (т. е. GPU, если диспетчер DXGI был предоставлен, ЦП в противном случае).
  • Если драйвер AV Stream (или подключаемый модуль пользовательского режима) обрабатывает исправление поворота, поле поворота структуры PLD ACPI должно иметь значение 0.

Замечание

При использовании автокоррекции изготовители оборудования и IHV не должны указывать фактическую ориентацию датчика в поле _PLD Rotation. В этом случае поле поворота должно указывать ориентацию после исправления: 0 градусов.

Объявите через FSSensorOrientation

; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270

Объявив ненулевую степенью ориентацию датчика с помощью тега реестра FSSensorOrientation, поток камеры может исправить захваченный кадр, прежде чем представить его приложению.

Конвейер оптимизирует логику поворота, используя ресурсы GPU или ЦП на основе варианта использования и запроса приложения или сценария.

Поворот ACPI PLD

Поле поворота структуры PLD ACPI должно иметь значение 0. Это позволяет избежать путаницы приложений, которые могут использовать сведения PLD для исправления кадра.

Сведения о типе носителя

Тип носителя, представленный драйвером, должен быть неоткорректированным типом носителя. При информировании конвейера камеры о ненулевом смещении с помощью записи FSSensorOrientation, информация о типе медиа, представленная датчиком, должна отображать некорректированный тип медиа. Например, если датчик установлен со смещением на 90 градусов по часовой стрелке, то вместо пропорций 16:9 результирующее видео будет 9:16, и соотношение сторон 9:16 должно быть представлено конвейеру камеры.

Это необходимо для правильной настройки процесса поворота счетчика: конвейеру требуется тип входного носителя и нужный тип выходного носителя приложения.

Сюда входит информация о длине шага. Сведения о шагах должны быть представлены для незаменяемого типа носителя конвейеру камеры.

Подраздел реестра

Запись реестра FSSensorOrientation должна быть опубликована на узле интерфейса устройства. Рекомендуемый подход — объявить это как директиву AddReg во время объявления директивы AddInterface в INF драйвера камеры.

Данные, представленные в FSSensorOrientation, должны быть REG_DWORD, а допустимые значения — 90, 180 и 270. Любое другое значение будет рассматриваться как смещение в 0 градусов (т. е. игнорируется).

Каждое значение представляет ориентацию датчика в градусах по часовой стрелке. Конвейер камеры исправит результирующий видеокадр, вращая видео на такую же величину против часовой стрелки: т. е. заявление о вращении на 90 градусов по часовой стрелке приведет к вращению на 90 градусов против часовой стрелки, чтобы вернуть результирующий видеокадр обратно к смещению на 0 градусов.

Дескриптор ОС MS OS 1.0

Для USB-камер FSSensorOrientation также может публиковаться через дескрипторы MSOS.

Дескриптор ОС MS OS 1.0 состоит из двух компонентов:

  • Раздел заголовка фиксированной длины
  • Один или несколько разделов настраиваемых свойств переменной длины, которые следует разделу заголовка

Раздел заголовка MS OS DESCRIPTOR 1.0

В разделе заголовка описывается одно пользовательское свойство (профиль проверки подлинности лиц).

Offset Поле Размер (в байтах) Ценность Описание
0 dwLength 4 <>
4 bcdVersion 2 0x0100 Версия 1.0
6 wIndex 2 0x0005 Дескриптор расширенных свойств ОС
8 wCount 2 0x0001 Одно пользовательское свойство

Раздел свойств Custom MS OS DESCRIPTOR 1.0

Offset Поле Размер (в байтах) Ценность Описание
0 dwSize 4 0x00000036 (54) Общий размер (в байтах) для этого свойства.
4 dwPropertyDataType 4 0x00000004 REG_DWORD_LITTLE_ENDIAN
8 wPropertyNameLength 2 0x00000024 (36) Размер (в байтах) имени свойства.
10 bPropertyName 50 UVC-FSSensorOrientation Строка UVC-FSSensorOrientation в Юникоде.
шестьдесят dwPropertyDataLength 4 0x00000004 4 байта для данных свойств (sizeof(DWORD)).
64 bPropertyData 4 Угол смещения в градусах по часовой стрелке. Допустимые значения: 90, 180 и 270.

Дескриптор ОС MS 2.0

Расширенный дескриптор MSOS 2.0 можно использовать для определения значений реестра для добавления поддержки FSSensorOrientation. Это делается с помощью дескриптора свойства реестра Microsoft OS 2.0.

Для записи реестра UVC-FSSensorOrientation представлен следующий образец набора дескрипторов MSOS 2.0:

UCHAR Example2_MSOS20DescriptorSet_UVCFSSensorOrientationForFutureWindows[0x3C] =
{
    //
    // Microsoft OS 2.0 Descriptor Set Header
    //
    0x0A, 0x00,                 // wLength - 10 bytes
    0x00, 0x00,                 // MSOS20_SET_HEADER_DESCRIPTOR
    0x00, 0x00, 0x0?, 0x06,     // dwWindowsVersion – 0x060?0000 for future Windows version
    0x4A, 0x00,                 // wTotalLength – 74 bytes

    //
    // Microsoft OS 2.0 Registry Value Feature Descriptor
    //
    0x40, 0x00,                 // wLength - 64 bytes
    0x04, 0x00,                 // wDescriptorType – 4 for Registry Property
    0x04, 0x00,                 // wPropertyDataType - 4 for REG_DWORD_LITTLE_ENDIAN
    0x32, 0x00,                 // wPropertyNameLength – 50 bytes
    0x55, 0x00, 0x56, 0x00,     // Property Name - "UVC-FSSensorOrientation"
    0x43, 0x00, 0x2D, 0x00,
    0x46, 0x00, 0x53, 0x00,
    0x53, 0x00, 0x65, 0x00,
    0x6E, 0x00, 0x73, 0x00,
    0x6F, 0x00, 0x72, 0x00,
    0x4F, 0x00, 0x72, 0x00,
    0x69, 0x00, 0x65, 0x00,
    0x6E, 0x00, 0x74, 0x00,
    0x61, 0x00, 0x74, 0x00,
    0x69, 0x00, 0x6F, 0x00,
    0x6E, 0x00, 0x00, 0x00,
    0x00, 0x00,
    0x04, 0x00,                 // wPropertyDataLength – 4 bytes
    0x5A, 0x00, 0x00, 0x00      // PropertyData – 0x0000005A (90 degrees offset)
}

Объявление с помощью сведений PLD ACPI

В качестве варианта последней возможности данные PLD можно использовать, как описано выше, чтобы информировать приложение, что видеокадр должен быть скорректирован перед отрисовкой или кодированием. Однако, как уже говорилось, многие существующие приложения не используют сведения PLD и не обрабатывают поворот кадров, поэтому приложения могут не иметь возможности правильно отображать полученное видео.

На следующих рисунках показаны значения поля поворота _PLD для каждой конфигурации оборудования:

Поворот: 0 градусов по часовой стрелке

Фигура с поворотом на 0 градусов.

На рисунке выше:

  • Изображение слева иллюстрирует сцену для съемки.

  • На рисунке в середине показано, как сцена просматривается датчиком CMOS, физический порядок чтения которого начинается с левого нижнего угла, движущегося слева направо вверх.

  • Изображение справа представляет выходные данные драйвера камеры. В этом примере содержимое медиабуфера может быть непосредственно отображено в его естественной ориентации без дополнительного поворота. Следовательно, поле ACPI _PLD поворота имеет значение 0.

Поворот: 90 градусов по часовой стрелке

Фигура поворота на 90 градусов.

В этом случае содержимое буфера мультимедиа поворачивается на 90 градусов по часовой стрелке по сравнению с исходной сценой. В результате поле вращения ACPI _PLD имеет значение 2.

Поворот: 180 градусов по часовой стрелке

Фигура поворота на 180 градусов.

В этом случае содержимое буфера мультимедиа повернуто на 180 градусов по сравнению с исходной сценой. В результате поле Rotation _PLD ACPI имеет значение 4.

Поворот: 270 градусов по часовой стрелке

Фигура поворота в 270 градусов.

В этом случае содержимое буфера мультимедиа повернуто на 270 градусов по сравнению с исходной сценой. В результате поле Rotation _PLD в ACPI имеет значение 6.