Udostępnij przez


Obsługa sterownika dla orientacji aparatu

Ważne

Metoda autokorekty omówiona w dalszej części tego tematu jest zalecanym rozwiązaniem do montażu czujników kamery w orientacji niereferencyjnej. Celem tego jest zapewnienie zgodności aplikacji, ponieważ większość aplikacji już napisanych do korzystania ze strumieni wideo z aparatu nie wie, jak sprawdzić ani poprawić dane o rotacji. Uważnie przejrzyj informacje w poniższej sekcji autokorektowej.

W miarę wprowadzania różnych formatów urządzeń komputerowych, niektóre ograniczenia fizyczne powodują zamontowanie czujników kamer w nietradycyjnej orientacji. W związku z tym konieczne jest prawidłowe opisanie systemu operacyjnego i aplikacji, sposób instalowania czujników, aby wynikowy film wideo mógł być poprawnie renderowany/rejestrowany.

Począwszy od okna 10, wersja 1607, wszystkie sterowniki aparatu są wymagane do jawnego określenia orientacji aparatu niezależnie od tego, czy aparat jest zainstalowany zgodnie z minimalnymi wymaganiami sprzętowymi. W szczególności sterownik kamery musi ustawić nowo wprowadzone pole, Rotacja, w strukturze ACPI _PLD skojarzonej z interfejsem urządzenia przechwytywania:

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;

W przypadku aparatu pole Rotacja w strukturze _PLD ACPI określa liczbę stopni ('0' dla 0°, '2' dla 90°, '4' dla 180°, i '6' dla 270°) przechwycona ramka jest obracana względem ekranu, podczas gdy wyświetlacz jest w orientacji natywnej.

Na podstawie wartości w polu Rotacja aplikacja może w razie potrzeby wykonać dodatkową rotację w celu poprawnego renderowania przechwyconych ramek.

Wartości obrotu

W przypadku tych urządzeń, których kamery i wyświetlacze dzielą tę samą obudowę (lub pokrywę), możliwe jest zamontowanie tych peryferiów na różnych powierzchniach, z każdym z nich obróconym o stały, lecz dowolnie wybrany kąt na swojej płaszczyźnie. W związku z tym aplikacja potrzebuje mechanizmu opisującego relację przestrzenną między dwoma urządzeniami peryferyjnymi, tak aby przechwycona ramka mogła zostać transponowana na powierzchnię renderowania w odpowiedniej orientacji.

Jednym ze sposobów rozwiązania problemu jest użycie struktury _PLD ACPI, która ma już zdefiniowane koncepcje powierzchni i stopni obrotu . Na przykład struktura _PLD ma już pole panelu , które określa powierzchnię, na której znajduje się urządzenie peryferyjne:

Pole tablicy ACPI PLD.

Definicja pola panelu _PLD ACPI (wersja 5.0a)

Dwa następne diagramy ilustrują wizualnie definicję każdego panelu:

Definicje panelu dla komputerów stacjonarnych i większości urządzeń

Definicje panelu — pulpit.

Definicje panelu dla składanych urządzeń

Definicje paneli — składane urządzenia.

W rzeczywistości pojęcie "panelu ACPI" jest już przyjęte przez system Windows, gdzie:

  • Interfejs urządzenia kamery jest skojarzony z strukturą _PLD, z polem Panel ustawionym odpowiednio, jeśli urządzenie przechwytywania jest statycznie zamontowane w ustalonej lokalizacji.

  • Aplikacja może pobrać panel, na którym znajduje się urządzenie przechwytywania, wywołując właściwość Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .

Struktura _PLD ACPI ma również pole Rotacja zdefiniowane w następujący sposób:

Definicja pola rotacji _PLD ACPI (Rev 5.0a)

Definicje pól rotacji ACPI _PLD.

Zamiast używać powyższej definicji, jak to jest, dodatkowo udoskonalamy ją, aby uniknąć niejednoznaczności:

  • W przypadku aparatu pole Rotacja w strukturze _PLD ACPI określa, o ile stopni ('0' dla 0°, '2' dla 90°, '4' dla 180°, i '6' dla 270°) należy obrócić przechwyconą ramkę względem ekranu, gdy wyświetlacz znajduje się w orientacji natywnej.

Podstawowa orientacja pozioma a podstawowa orientacja pionowa

W systemie Windows można wykonywać zapytania dotyczące natywnej orientacji ekranu, poprzez wywołanie właściwości Windows.Graphics.Display.DisplayInformation.NativeOrientation, która zwraca wartość Pejzaż lub Portret:

Wyświetla wzorzec skanowania orientacji natywnej.

Niezależnie od zwracanej wartości NativeOrientation wzorzec skanowania wyświetlania logicznego rozpoczyna się od lewego górnego rogu ekranu przechodzącego od lewej do prawej w dół (patrz Rysunek 5). W przypadku tych urządzeń, których domyślna orientacja fizyczna jest niewyjaśniona, ta właściwość nie tylko oznacza lokalizację górnego panelu ACPI, ale także zapewnia relację przestrzenną między buforem wyjściowym aparatu a powierzchnią renderowania.

Należy pamiętać, że w przeciwieństwie do aparatu właściwość NativeOrientation nie jest oparta na ACPI i w związku z tym nie ma struktury _PLD. Jest to prawdą, nawet jeśli ekran jest statycznie zainstalowany na urządzeniu.

Podczas instalowania na pionowym urządzeniu podstawowym sterowniki kamer muszą mieć świadomość, że większość aplikacji traktuje urządzenie jako wyjście bufora wyjściowego kamery poziomej niezależnie od rzeczywistej orientacji buforu wyjściowego aparatu. Z tego powodu zalecamy, aby sterowniki aparatów wyjściowych generowały bufor kamery z przesunięciem orientacji o 90 stopni od portretu w trybie NativeOrientation, gdy urządzenie działa w trybie pionowym jako podstawowym. Umożliwi to aplikacjom wykonującym tę dodatkową rotację na urządzeniach pionowych w celu skorygowania rotacji do oczekiwanej orientacji. Można to zweryfikować przy użyciu aplikacji aparatu z próbką rotacji.

Przesunięcie montażu

IHV/OEM są zdecydowanie zachęcani do unikania instalowania czujnika z przesunięciem innym niż 0 stopni, aby zachować zgodność z aplikacjami. Wiele istniejących i starszych aplikacji nie wie, aby wyszukać tabelę PLD ACPI, ani nie podejmie próby skorygowania przesunięcia innego niż 0 stopni. W związku z tym w przypadku takich aplikacji wynikowy film wideo zostanie niepoprawnie renderowany.

W przypadkach, gdy IHV/OEM nie mogą zainstalować czujnika w ustawieniu 0 stopni zgodnie z powyższym opisem, zaleca się następujące kroki łagodzące w kolejności preferencji:

  1. Automatyczne korygowanie orientacji innej niż 0 stopni w sterowniku kamery (w trybie jądra ze sterownikiem miniport strumienia AV lub w trybie użytkownika za pomocą wtyczki, na przykład Device MFT lub MFT0), aby wynikowe ramki były w orientacji 0 stopni.

  2. Zadeklaruj orientację inną niż 0 stopni za pomocą tagu FSSensorOrientation, aby ścieżka przetwarzania aparatu mogła poprawić przechwycony obraz.

  3. Zadeklaruj orientację inną niż 0 stopni w tabeli PLD ACPI, jak opisano powyżej.

Typy skompresowanych/zakodowanych multimediów

W przypadku typów nośników skompresowanych i/lub zakodowanych (takich jak MJPG, JPEG, H264, HEVC) nie można użyć poprawnego potoku. W związku z tym typy nośników skompresowanych/zakodowanych zostaną odfiltrowane, jeśli właściwość FSSensorOrientation jest ustawiona na wartość inną niż zero.

W przypadku typów multimediów MJPG (takich jak te z kamery UVC), potok Frame Servera zapewnia automatycznie dekodowany typ multimediów (NV12 lub YUY2 dla aplikacji bazujących na DirectShow (DShow)). Zostanie wyświetlony automatycznie zdekodowany i poprawiony typ nośnika, ale oryginalny format MJPG nie będzie.

[! UWAGA!] Jeśli skompresowane/zakodowane typy multimediów muszą być uwidocznione w aplikacjach, IHV/ODM nie mogą korzystać z korygowania FSSensorOrientation. Zamiast tego należy dokonać korekty przez sterownik aparatu (w trybie jądra za pośrednictwem sterownika AV Stream lub w trybie użytkownika za pośrednictwem DMFT/MFT0).

Autokorektowanie za pośrednictwem miniportu strumienia AV/Urządzenia MFT/MFT0

Zalecanym scenariuszem, jeśli czujników nie można zamontować z przesunięciem o 0 stopni, jest umożliwienie sterownikowi miniportu AV Stream (lub wtyczce trybu użytkownika w formie DMFT lub MFT0) poprawienia wynikowej przechwyconej ramki, tak aby była przedstawiona potokowi z przesunięciem o 0 stopni.

Podczas poprawiania ramki wideo z AV Stream Miniport i/lub wtyczki urządzenia MFT/MFT0, deklaracja typu nośnika wynikająca z tego musi być oparta na poprawionej ramce. Jeśli czujnik jest zamontowany z przesunięciem o 90 stopni, tak że wynikowe wideo ma współczynnik proporcji 9:16 z czujnika, ale poprawione wideo miałoby współczynnik 16:9, typ nośnika musi zadeklarować współczynnik proporcji 16:9.

Obejmuje to wynikowe informacje o kroku. Jest to konieczne, ponieważ komponent odpowiedzialny za korekcję jest kontrolowany przez IHV/OEM, a potok przetwarzania obrazu nie ma wglądu w ramkę wideo, dopóki nie zostanie skorygowana.

Zdecydowanie zaleca się wykonanie korekty w trybie użytkownika, a kontrakt API między potokiem a wtyczką trybu użytkownika musi być przestrzegany. W szczególności w przypadku korzystania z DMFT lub MFT0, gdy IMFDeviceTransform::ProcessMessage lub IMFTransform::ProcessMessage jest wywoływane z komunikatem MFT_MESSAGE_SET_D3D_MANAGER, wtyczka trybu użytkownika musi być zgodna z następującymi wytycznymi:

  • Jeśli nie podano menedżera D3D (ulParam komunikatu wynosi 0), wtyczka trybu użytkownika nie może wywoływać żadnych operacji procesora GPU w celu obsługi korekty rotacji. Wynikowa ramka musi być umieszczona w pamięci systemowej.
  • Jeśli menedżer D3D jest podany (ulParam wiadomości jest IUnknown menedżera DXGI), ten menedżer DXGI musi być używany do korekcji rotacji, a wynikowa ramka musi być pamięcią GPU.
  • Wtyczka trybu użytkownika musi również obsługiwać komunikat menedżera D3D w czasie działania programu. Gdy zostanie wydany komunikat MFT_MESSAGE_SET_D3D_MANAGER, następna ramka utworzona przez wtyczkę musi odpowiadać żądanemu typowi pamięci (tj. pamięci GPU, jeśli podano menedżera DXGI, lub pamięci CPU w przeciwnym razie).
  • Gdy sterownik strumienia AV (lub wtyczka trybu użytkownika) obsługuje korektę rotacji, pole rotacja struktury PLD ACPI musi być ustawione na 0.

Uwaga / Notatka

Gdy jest używana funkcja Autokorekta, producenci OEM i IHV nie mogą podawać rzeczywistej orientacji czujnika za pośrednictwem pola _PLD Rotacja. W takim przypadku pole Rotacja musi wskazywać orientację po korekcie: 0 stopni.

Deklarowanie za pomocą funkcji FSSensorOrientation

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

Deklarując orientację inną niż 0 stopni czujnika za pośrednictwem tagu rejestru FSSensorOrientation, potok aparatu może poprawić przechwyconą ramkę przed przedstawieniem jej aplikacji.

Pipeline zoptymalizuje logikę rotacji, korzystając z zasobów GPU lub CPU na podstawie przypadku użycia i żądania lub scenariusza aplikacji.

Rotacja PLD ACPI

Pole rotacji w strukturze ACPI PLD musi mieć wartość 0. Pozwala to uniknąć mylących aplikacji, które mogą używać informacji PLD do poprawiania ramki.

Informacje o typie nośnika

Typ nośnika przedstawiony przez sterownik musi być niekorektowanym typem nośnika. Podczas informowania ścieżki przetwarzania obrazu o przesunięciu różnym od 0 stopni przy użyciu wpisu FSSensorOrientation informacje o typie nośnika prezentowane przez czujnik muszą być nieskorygowanym typem nośnika. Jeśli na przykład czujnik jest zamontowany z obrotem o 90 stopni zgodnie z ruchem wskazówek zegara, to, zamiast współczynnika proporcji 16:9, wynikowy film wideo ma proporcje 9:16; typ nośnika odpowiadający proporcjom 9:16 musi być przedstawiony w potoku kamery.

Jest to konieczne, aby upewnić się, że potok może poprawnie skonfigurować proces przeciwnej rotacji: potok wymaga typu mediów wejściowych oraz żądanego typu mediów wyjściowych aplikacji.

Obejmuje to informacje kroków. Informacje dotyczące przesunięcia muszą być przedstawione dla niepoprawionego typu nośnika w potoku aparatu.

Podklucz rejestru

Wpis rejestru FSSensorOrientation musi zostać opublikowany w węźle interfejsu urządzenia. Zalecaną metodą jest zadeklarowanie tego jako dyrektywy AddReg podczas deklaracji dyrektywy AddInterface w pliku INF sterownika aparatu.

Dane przedstawione w fsSensorOrientation muszą być REG_DWORD i jedynymi prawidłowymi wartościami zaakceptowane będą 90, 180 i 270. Każda inna wartość będzie traktowana jako przesunięcie o 0 stopni (tj. ignorowana).

Każda wartość reprezentuje orientację czujnika w stopniach zgodnie z ruchem wskazówek zegara. Potok kamery poprawi wynikową ramkę wideo, obracając wideo o taką samą ilość licznika zgodnie z ruchem wskazówek zegara: tj. deklaracja 90 stopni zgodnie z ruchem wskazówek zegara spowoduje 90 stopni licznika obrotu zgodnie z ruchem wskazówek zegara, aby przywrócić wynikową ramkę wideo z powrotem do 0 stopni przesunięcia.

Deskryptor systemu operacyjnego MS 1.0

W przypadku kamer opartych na USB fsSensorOrientation można również opublikować za pośrednictwem deskryptorów MSOS.

Deskryptor MS OS 1.0 ma dwa składniki:

  • Sekcja nagłówka o stałej długości
  • Co najmniej jedna sekcja właściwości niestandardowych o zmiennej długości, które następują po sekcji nagłówka

Sekcja nagłówka opisu systemu MS OS 1.0

W sekcji nagłówka opisano jedną właściwość niestandardową (Profil autoryzacji twarzy).

Przesunięcie (No changes needed) Rozmiar (bajty) Wartość Opis
0 dwLength 4 <>
4 bcdVersion 2 0x0100 Wersja 1.0
6 wIndex 2 0x0005 Deskryptor rozszerzonej właściwości systemu operacyjnego
8 wCount 2 0x0001 Jedna właściwość niestandardowa

Sekcja właściwości Custom MS OS DESCRIPTOR 1.0

Przesunięcie (No changes needed) Rozmiar (bajty) Wartość Opis
0 dwSize 4 0x00000036 (54) Całkowity rozmiar (w bajtach) dla tej właściwości.
4 dwPropertyDataType 4 0x00000004 REG_DWORD_LITTLE_ENDIAN
8 wPropertyNameLength 2 0x00000024 (36) Rozmiar (w bajtach) nazwy właściwości.
10 bPropertyName 50 UVC-FSSensorOrientation Ciąg "UVC-FSSensorOrientation" w standardze Unicode.
60 dwPropertyDataLength 4 0x00000004 4 bajty dla danych właściwości (sizeof(DWORD)).
64 bPropertyData 4 Przesunięcie kąta w stopniach zgodnie z ruchem wskazówek zegara. Prawidłowe wartości to 90, 180 i 270.

Deskryptor systemu operacyjnego MS 2.0

Rozszerzony deskryptor MSOS 2.0 może służyć do definiowania wartości rejestru w celu dodania obsługi FSSensorOrientation. Odbywa się to przy użyciu deskryptora właściwości rejestru systemu operacyjnego Microsoft OS 2.0.

Dla wpisu rejestru UVC-FSSensorOrientation poniżej przedstawiono przykładowy zestaw deskryptorów 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)
}

Deklarowanie za pośrednictwem informacji PLD ACPI

W ostateczności można wykorzystać informacje PLD zgodnie z powyższym opisem, aby zasygnalizować aplikacji, że ramka wideo musi zostać poprawiona przed wyrenderowaniem/zakodowaniem. Jednak zgodnie z opisem wiele istniejących aplikacji nie korzysta z informacji PLD ani nie obsługuje rotacji ramek, więc będą istnieć scenariusze, w których aplikacje mogą nie być w stanie poprawnie renderować wynikowego wideo.

Na poniższych ilustracjach przedstawiono wartości pola _PLD Rotation dla każdej konfiguracji sprzętu:

Obrót: 0 stopni zgodnie z ruchem wskazówek zegara

Rysunek przedstawiający obrót o 0 stopni.

Na powyższej ilustracji:

  • Obraz po lewej ilustruje scenę do uchwycenia.

  • Obraz w środku przedstawia sposób wyświetlania sceny przez czujnik CMOS, którego fizyczna kolejność odczytu zaczyna się od lewego dolnego rogu, przesuwając się z lewej do prawej oraz ku górze.

  • Obraz po prawej stronie reprezentuje dane wyjściowe sterownika aparatu. W tym przykładzie zawartość buforu danych multimedialnych może być renderowana bezpośrednio, gdy ekran jest w swojej natywnej orientacji bez dodatkowej rotacji. W związku z tym pole ACPI _PLD Rotation ma wartość 0.

Obrót: 90 stopni zgodnie z ruchem wskazówek zegara

Rysunek obrócony o 90 stopni.

W tym przypadku zawartość buforu multimedialnego jest obracana o 90 stopni zgodnie z ruchem wskazówek zegara w porównaniu z oryginalną sceną. W rezultacie pole ACPI _PLD Rotation ma wartość 2.

Obrót: 180 stopni zgodnie z ruchem wskazówek zegara

Figura obrócona o 180 stopni.

W tym przypadku zawartość buforu multimedialnego jest obracana o 180 stopni zgodnie z ruchem wskazówek zegara w porównaniu z oryginalną sceną. W rezultacie pole ACPI _PLD Rotation ma wartość 4.

Obrót: 270 stopni zgodnie z ruchem wskazówek zegara

Rysunek obrócony o 270 stopni.

W tym przypadku zawartość buforu multimediów jest obracana o 270 stopni zgodnie z ruchem wskazówek zegara w porównaniu z oryginalną sceną. W rezultacie pole ACPI _PLD Rotacja ma wartość 6.