Supporto driver per l'orientamento della fotocamera
Importante
Il metodo corretto automatico descritto più avanti in questo argomento è la soluzione consigliata per il montaggio dell'orientamento non di riferimento dei sensori della fotocamera. Ciò consente di garantire la compatibilità delle app perché la maggior parte delle applicazioni già scritte per l'uso dei feed della fotocamera non è in grado di verificare, né di correggere le informazioni sulla rotazione. Esaminare attentamente le informazioni nella sezione correzione automatica riportata di seguito.
Man mano che vengono introdotti diversi fattori di forma, alcuni dei vincoli fisici comportano la montaggio dei sensori della fotocamera in un orientamento non tradizionale. Per questo motivo, è necessario descrivere correttamente il sistema operativo e l'applicazione, come vengono montati i sensori in modo che il video risultante possa essere sottoposto a rendering o registrato correttamente.
A partire da Window 10, versione 1607, tutti i driver della fotocamera devono specificare in modo esplicito l'orientamento della fotocamera indipendentemente dal fatto che la fotocamera sia montata in base ai requisiti hardware minimi. In particolare, un driver della fotocamera deve impostare un campo appena introdotto, Rotation, nella struttura ACPI _PLD associata a un'interfaccia del dispositivo di acquisizione:
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;
Per la fotocamera, il campo Rotazione in una struttura ACPI _PLD specifica il numero di gradi ('0' per 0°, '2' per 90°, '4' per 180°, e '6' per 270°) un fotogramma acquisito viene ruotato rispetto allo schermo mentre lo schermo è nell'orientamento nativo.
In base al valore nel campo Rotazione , un'applicazione può eseguire una rotazione aggiuntiva, se necessario, per eseguire correttamente il rendering dei fotogrammi acquisiti.
Valori di rotazione
Per i dispositivi le cui fotocamere e schermi condividono lo stesso alloggiamento (ocase dienclosure/), è possibile montare queste periferiche su superfici diverse con ognuna di esse ruotate da un gradi fisso ma arbitrario sul rispettivo piano. Di conseguenza, un'applicazione necessita di un meccanismo per descrivere la relazione spaziale tra le due periferiche in modo che un frame acquisito possa essere trasposto nella superficie di rendering nell'orientamento corretto.
Un modo per risolvere il problema consiste nell'utilizzare la struttura ACPI _PLD che ha già i concetti di superficie e gradi di rotazione definiti. Ad esempio, la struttura _PLD ha già un campo pannello che specifica la superficie in cui risiede una periferica:
Definizione del campo ACPI _PLD Pannello (rev. 5.0a)
I due diagrammi successivi illustrano visivamente la definizione di ogni pannello:
Definizioni di pannello per PC desktop e la maggior parte dei dispositivi
Definizioni dei pannelli per i dispositivi piegabili
In realtà, il concetto di "pannello ACPI" è già adottato da Windows dove:
Un'interfaccia del dispositivo fotocamera è associata a una struttura _PLD con il campo Pannello impostato di conseguenza se un dispositivo di acquisizione viene montato in modo statico in una posizione fissa.
Un'applicazione può recuperare il pannello in cui risiede un dispositivo di acquisizione chiamando la proprietà Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .
La struttura ACPI _PLD ha anche un campo Rotation definito come segue:
Definizione del campo ACPI _PLD Rotation (Rev 5.0a)
Anziché usare la definizione precedente così come è, è possibile perfezionarla ulteriormente per evitare ambiguità:
- Per la fotocamera, il campo Rotazione in una struttura ACPI _PLD specifica il numero di gradi ('0' per 0°, '2' per 90°, '4' per 180°, e '6' per 270°) un fotogramma acquisito viene ruotato rispetto allo schermo mentre lo schermo è nell'orientamento nativo.
Orizzontale primario e verticale primario
In Windows è possibile eseguire una query sull'orientamento di visualizzazione nativo chiamando la proprietà Windows.Graphics.Display.DisplayInformation.NativeOrientation, che restituisce Orizzontale o Verticale:
Indipendentemente dal valore restituito da NativeOrientation , il modello di analisi della visualizzazione logica inizia dall'angolo superiore sinistro dello schermo che si sposta da sinistra verso destra verso il basso (vedere la figura 5). Per i dispositivi il cui orientamento fisico predefinito è inexplicit, questa proprietà non solo implica la posizione di un pannello ACPI Top , ma fornisce anche la relazione spaziale tra un buffer di output della fotocamera e la superficie di rendering.
Si noti che, a differenza della fotocamera, la proprietà NativeOrientation non è basata su ACPI e pertanto non ha una struttura _PLD. Questo vale anche se uno schermo viene montato in modo statico in un dispositivo.
Quando si monta su un dispositivo verticale primario, i driver della fotocamera devono essere consapevoli che la maggior parte delle applicazioni considererà il dispositivo come output di un buffer di output della fotocamera orizzontale indipendentemente dall'orientamento effettivo del buffer di output della fotocamera. Per questo motivo, è consigliabile che i driver della fotocamera restituisca un buffer della fotocamera con un offset di orientamento di 90 gradi rispetto a NativeOrientation Portrait quando si usa un dispositivo verticale primario. Ciò consentirà quindi alle applicazioni che eseguono questa rotazione aggiuntiva nei dispositivi verticali di correggere la rotazione all'orientamento previsto. Questa verifica può essere eseguita usando l'applicazione fotocamera con l'esempio di rotazione.
Montaggio offset
Gli OEM/IHV sono fortemente invitati a evitare di montare il sensore in un offset non di 0 gradi per mantenere la compatibilità delle app. Molte app esistenti e legacy non sanno cercare la tabella PLD dell'ACPI, né tenteranno di correggere l'offset non di gradi. Di conseguenza, per tali app il rendering del video risultante non verrà eseguito correttamente.
Nei casi in cui gli OEM/IHV non sono in grado di montare il sensore con orientamento di 0 gradi, come descritto in precedenza, i passaggi di mitigazione seguenti sono consigliati nell'ordine di preferenza:
Correggere automaticamente l'orientamento non di grado all'interno del driver della fotocamera (in modalità kernel con il driver miniport di flusso AV o in modalità utente usando un plug-in, ad esempio Device MFT o MFT0), in modo che i fotogrammi di output risultanti siano nell'orientamento di 0 gradi.
Dichiarare l'orientamento diverso da 0 gradi tramite il tag FSSensorOrientation in modo che la pipeline della fotocamera possa correggere l'immagine acquisita.
Dichiarare l'orientamento diverso da 0 gradi nella tabella PLD dell'ACPI, come descritto in precedenza.
Tipi di supporti compressi/codificati
Per i tipi di supporti compressi e/o codificati (ad esempio MJPG, JPEG, H264, HEVC), non è possibile usare la pipeline corretta. Per questo motivo, i tipi di supporti compressi/codificati verranno filtrati se FSSensorOrientation è impostato su un valore diverso da zero.
Nel caso dei tipi di supporti MJPG (ad esempio quelli di una fotocamera UVC), la pipeline server frame fornisce un tipo di supporto decodificato automaticamente (NV12 o YUY2 per applicazioni basate su DShow). Verrà presentato il tipo di supporto decodificato e corretto automaticamente, ma il formato MJPG originale non verrà visualizzato.
[! NOTA!] Se i tipi di supporti compressi/codificati devono essere esposti alle applicazioni, IHV/ODMs non devono utilizzare la correzione FSSensorOrientation. Al contrario, la correzione deve essere eseguita dal driver della fotocamera (in modalità kernel tramite il driver av Stream o in modalità utente tramite DMFT/MFT0).
Correzione automatica tramite AV Stream Miniport/Dispositivo MFT/MFT0
Lo scenario consigliato se i sensori non possono essere montati con un offset di 0 gradi, deve avere il driver AV Stream miniport (o i plug-in modalità utente sotto forma di DMFT o MFT0) correggere il frame acquisito risultante in modo che venga esposto alla pipeline in un offset di 0 gradi.
Quando si corregge il fotogramma video dall'AV Stream Miniport e/o dal plug-in Device MFT/MFT0, la dichiarazione del tipo di supporto risultante deve essere basata sul fotogramma corretto. Se il sensore viene montato in corrispondenza di un offset di 90 gradi in modo che il video risultante sia di 9:16 proporzioni dal sensore, ma il video corretto sarà 16:9, il tipo di supporto deve dichiarare le proporzioni 16:9.
Sono incluse le informazioni sullo stride risultanti. Ciò è necessario perché il componente responsabile dell'esecuzione della correzione è controllato dall'IHV/OEM e la pipeline della fotocamera non ha visibilità sul fotogramma video, tranne dopo che è stata corretta.
È consigliabile eseguire la correzione in modalità utente e il contratto API tra la pipeline e il plug-in modalità utente deve essere seguito. In particolare, quando si usa DMFT o MFT0, quando imfDeviceTransform::P rocessMessage o IMFTransform::P rocessMessage viene richiamato con un messaggio di MFT_MESSAGE_SET_D3D_MANAGER, il plug-in modalità utente deve rispettare le linee guida seguenti:
- Se non viene fornito alcun gestore D3D (ulParam del messaggio è 0), il plug-in modalità utente non deve richiamare alcuna operazione GPU per gestire la correzione di rotazione. E il frame risultante deve essere fornito nella memoria di sistema.
- Se viene fornito il gestore D3D (l'ulParam del messaggio è l'IUnknown di un manager DXGI), il manager DXGI deve essere usato per la correzione di rotazione e il frame risultante deve essere memoria GPU.
- Il plug-in modalità utente deve anche gestire il messaggio di gestione D3D durante il runtime. Quando viene generato il messaggio di MFT_MESSAGE_SET_D3D_MANAGER, il frame successivo prodotto dal plug-in deve corrispondere al tipo di memoria richiesto (ad esempio, GPU se è stato fornito DXGI Manager, CPU in caso contrario).
- Quando il driver av Stream (o il plug-in modalità utente) gestisce la correzione di rotazione, il campo Rotazione della struttura PLD dell'ACPI deve essere impostato su 0.
Nota
Quando si usa Correzione automatica, gli OEM e gli IHD non devono annunciare l'orientamento effettivo del sensore tramite il campo _PLD Rotazione . In questo caso, il campo Rotazione deve indicare l'orientamento dopo la correzione: 0 gradi.
Dichiarare tramite FSSensorOrientation
; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270
Dichiarando l'orientamento diverso da 0 gradi del sensore tramite il tag del Registro di sistema FSSensorOrientation, la pipeline della fotocamera può correggere il fotogramma acquisito prima di presentarlo all'applicazione.
La pipeline ottimizza la logica di rotazione sfruttando le risorse GPU o CPU in base al caso d'uso e alla richiesta/scenario dell'app.
Rotazione PLD ACPI
Il campo Rotazione della struttura ACPI PLD deve essere 0. Ciò consente di evitare confusione nelle applicazioni che possono usare le informazioni PLD per correggere il frame.
Informazioni sul tipo di supporto
Il tipo di supporto presentato dal driver deve essere il tipo di supporto non corretto. Quando si informa la pipeline della fotocamera dell'offset diverso da 0 gradi usando la voce FSSensorOrientation, le informazioni sul tipo di supporto presentate dal sensore devono essere il tipo di supporto non corretto. Ad esempio, se il sensore è montato con offset a 90 gradi in senso orario, invece di proporzioni di 16:9, il video risultante è 9:16, il tipo di supporto delle proporzioni 9:16 deve essere presentato alla pipeline della fotocamera.
Ciò è necessario per garantire che la pipeline possa configurare correttamente il processo di rotazione dei contatori: la pipeline richiede il tipo di supporto di input e il tipo di supporto di output desiderato dell'applicazione.
Sono incluse le informazioni sullo stride. Le informazioni sullo stride devono essere presentate per il tipo di supporto non corretto nella pipeline della fotocamera.
Sottochiave del Registro di sistema
La voce del Registro di sistema FSSensorOrientation deve essere pubblicata nel nodo Interfaccia dispositivo. L'approccio consigliato consiste nel dichiararlo come direttiva AddReg durante la dichiarazione di direttiva AddInterface nell'INF del driver della fotocamera.
I dati presentati in FSSensorOrientation devono essere un REG_DWORD e gli unici valori validi accettati saranno 90, 180 e 270. Qualsiasi altro valore verrà considerato come offset di 0 gradi ,ad esempio ignorato.
Ogni valore rappresenta l'orientamento del sensore in gradi in senso orario. La pipeline della fotocamera correggerà il fotogramma video risultante ruotando il video con la stessa quantità in senso orario: ad esempio, una dichiarazione a 90 gradi in senso orario comporterà una rotazione in senso orario contatore di 90 gradi per riportare il fotogramma video risultante a un offset di 0 gradi.
Descrittore del sistema operativo MS 1.0
Per le fotocamere basate su USB, FSSensorOrientation può anche essere pubblicato tramite descrittori MSOS.
Il descrittore del sistema operativo MS 1.0 ha due componenti:
- Sezione intestazione a lunghezza fissa
- Una o più sezioni personalizzate di lunghezza variabile, che segue la sezione intestazione
Sezione intestazione MS OS DESCRIPTOR 1.0
La sezione Intestazione descrive una singola proprietà personalizzata (Profilo di autenticazione viso).
Offset | Campo | Dimensioni (byte) | Valore | Descrizione |
---|---|---|---|---|
0 | dwLength | 4 | <> | |
4 | bcdVersion | 2 | 0x0100 | Versione 1.0 |
6 | Windex | 2 | 0x0005 | Descrittore del sistema operativo delle proprietà esteso |
8 | wCount | 2 | 0x0001 | Una proprietà personalizzata |
Sezione proprietà DI MS OS DESCRIPTOR 1.0 personalizzata
Offset | Campo | Dimensioni (byte) | Valore | Descrizione |
---|---|---|---|---|
0 | dwSize | 4 | 0x00000036 (54) | Dimensioni totali (in byte) per questa proprietà. |
4 | dwPropertyDataType | 4 | 0x00000004 | REG_DWORD_LITTLE_ENDIAN |
8 | wPropertyNameLength | 2 | 0x00000024 (36) | Dimensioni (in byte) del nome della proprietà. |
10 | bPropertyName | 50 | UVC-FSSensorOrientation | Stringa "UVC-FSSensorOrientation" in Unicode. |
60 | dwPropertyDataLength | 4 | 0x00000004 | 4 byte per i dati delle proprietà (sizeof(DWORD)). |
64 | bPropertyData | 4 | Angolo di offset in gradi in senso orario. | I valori validi sono 90, 180 e 270. |
Descrittore del sistema operativo MS 2.0
Il descrittore esteso MSOS 2.0 può essere usato per definire i valori del Registro di sistema per aggiungere il supporto di FSSensorOrientation. Questa operazione viene eseguita usando il descrittore di proprietà del Registro di sistema di Microsoft OS 2.0.
Per la voce del Registro di sistema UVC-FSSensorOrientation, viene illustrato un set di descrittore MSOS 2.0 di esempio:
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)
}
Dichiarare tramite informazioni PLD ACPI
Come opzione di ultima istanza, le informazioni PLD possono essere usate come descritto in precedenza per indicare all'applicazione che il fotogramma video deve essere corretto prima di essere sottoposto a rendering/codificato. Tuttavia, come indicato, molte applicazioni esistenti non usano le informazioni PLD né gestiscono la rotazione dei fotogrammi, quindi ci saranno scenari in cui le app potrebbero non essere in grado di eseguire correttamente il rendering del video risultante.
Le figure seguenti illustrano i valori del campo rotazione _PLD per ogni configurazione hardware:
Rotazione: 0 gradi in senso orario
Nella figura precedente:
L'immagine a sinistra illustra la scena da acquisire.
L'immagine in mezzo illustra come una scena viene visualizzata da un sensore LAMBDA il cui ordine di lettura fisico inizia dall'angolo in basso a sinistra che si sposta da sinistra verso destra verso l'alto.
L'immagine a destra rappresenta l'output del driver della fotocamera. In questo esempio il contenuto del buffer multimediale può essere eseguito direttamente mentre la visualizzazione è l'orientamento nativo senza rotazione aggiuntiva. Di conseguenza, il campo ACPI _PLD Rotation ha un valore pari a 0.
Rotazione: 90 gradi in senso orario
In questo caso, il contenuto del buffer multimediale viene ruotato di 90 gradi in senso orario rispetto alla scena originale. Di conseguenza, il campo ACPI _PLD Rotation ha un valore pari a 2.
Rotazione: 180 gradi in senso orario
In questo caso, il contenuto del buffer multimediale viene ruotato di 180 gradi in senso orario rispetto alla scena originale. Di conseguenza, il campo ACPI _PLD Rotation ha un valore pari a 4.
Rotazione: 270 gradi in senso orario
In questo caso, il contenuto del buffer multimediale viene ruotato di 270 gradi in senso orario rispetto alla scena originale. Di conseguenza, il campo ACPI _PLD Rotation ha un valore pari a 6.