Поделиться через


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

Важно!

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

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

Начиная с windows 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°) захваченный кадр поворачивается относительно экрана, пока дисплей находится в собственной ориентации.

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

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

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

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

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

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

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

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

Определения панелей — настольные компьютеры.

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

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

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

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

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

В структуре ACPI _PLD также есть поле Ротация, определенное следующим образом:

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

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

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

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

Альбомная первичная и книжная первичная

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

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

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

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

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

Смещение подключения

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

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

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

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

  3. Объявите ориентацию без 0 градусов в таблице PLD ACPI, как описано выше.

Сжатые/закодированные типы мультимедиа

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

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

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

Автоматическое исправление через AV Stream Miniport/Device MFT/MFT0

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

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

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

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

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

Примечание

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

Объявление через FSSensorOrientation

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

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

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

ACPI PLD Rotation

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

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

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

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

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

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

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

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

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

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

Для usb-камер FSSensorOrientation также можно опубликовать с помощью дескрипторов MSOS.

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

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

Раздел заголовка ДЕСКРИПТОРА ОС MS 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 в Юникоде.
60 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 Rotation имеет значение 2.

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

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

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

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

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

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