Prise en charge du pilote pour l’orientation de la caméra
Important
La méthode de correction automatique décrite plus loin dans cette rubrique est la solution recommandée pour le montage sans orientation de référence des capteurs de caméra. Cela permet de garantir la compatibilité des applications, car la majorité des applications déjà écrites pour utiliser des flux de caméra ne savent pas case activée pour, ni correctes pour les informations de rotation. Veuillez examiner attentivement les informations de la section de correction automatique ci-dessous.
À mesure que différents facteurs de forme informatiques sont introduits, certaines contraintes physiques entraînent le montage des capteurs de caméra dans une orientation non traditionnelle. Pour cette raison, il est nécessaire de décrire correctement au système d’exploitation et à l’application comment les capteurs sont montés afin que la vidéo résultante puisse être rendue/enregistrée correctement.
À compter de La fenêtre 10, version 1607, tous les pilotes d’appareil photo sont tenus de spécifier explicitement l’orientation de la caméra, que la caméra soit montée conformément à la configuration matérielle minimale requise. Plus précisément, un pilote de caméra doit définir un champ nouvellement introduit, Rotation, dans la structure _PLD ACPI associée à une interface de périphérique de capture :
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;
Pour la caméra, le champ Rotation dans une structure de _PLD ACPI spécifie le nombre de degrés ('0' pour 0°, '2' pour 90°, '4' pour 180° et '6' pour 270°) un cadre capturé est pivoté par rapport à l’écran pendant que l’affichage est dans son orientation native.
En fonction de la valeur du champ Rotation , une application peut effectuer une rotation supplémentaire, si nécessaire, afin d’afficher correctement les images capturées.
Valeurs de rotation
Pour les appareils dont les caméras et les écranspartagent le même boîtier (ou/ boîtier), il est possible de faire monter ces périphériques sur des surfaces différentes, chacun d’entre eux faisant l’objet d’une rotation d’un degré fixe mais arbitraire sur son plan respectif. Par conséquent, une application a besoin d’un mécanisme pour décrire la relation spatiale entre les deux périphériques, de sorte qu’une image capturée puisse être transposee sur la surface de rendu dans l’orientation correcte.
Une façon de résoudre le problème consiste à utiliser la structure _PLD ACPI qui a déjà les concepts de surface et de degrés de rotation définis. Par exemple, la structure _PLD a déjà un champ de panneau qui spécifie la surface sur laquelle réside un périphérique :
Définition du champ _PLD Panel ACPI (Rev. 5.0a)
Les deux diagrammes suivants illustrent visuellement la définition de chaque panneau :
Définitions de panneau pour les PC de bureau et la plupart des appareils
Définitions de panneau pour les appareils pliables
En fait, le concept de « panneau » ACPI est déjà adopté par Windows où :
Une interface d’appareil photo est associée à une structure _PLD avec le champ Panel défini en conséquence si un dispositif de capture est monté de manière statique à un emplacement fixe.
Une application peut récupérer le panneau sur lequel réside un appareil de capture en appelant la propriété Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .
La structure _PLD ACPI a également un champ Rotation défini comme suit :
Définition du champ de rotation _PLD ACPI (Rev 5.0a)
Au lieu d’utiliser la définition ci-dessus telle qu’elle est, nous l’affinons davantage pour éviter toute ambiguïté :
- Pour l’appareil photo, le champ Rotation dans une structure de _PLD ACPI spécifie le nombre de degrés ('0' pour 0°, '2' pour 90°, '4' pour 180° et '6' pour 270°) une image capturée est pivotée par rapport à l’écran pendant que l’affichage est dans son orientation native.
Paysage principal ou portrait principal
Dans Windows, vous pouvez interroger l’orientation d’affichage native en appelant la propriété Windows.Graphics.Display.DisplayInformation.NativeOrientation, qui retourne Paysage ou Portrait :
Quelle que soit la valeur retournée par NativeOrientation , le modèle d’analyse de l’affichage logique commence à partir du coin supérieur gauche de l’affichage et se déplace de gauche à droite vers le bas (voir la Figure 5). Pour les appareils dont l’orientation physique par défaut est inexplicitée, cette propriété implique non seulement l’emplacement d’un panneau ACPI Top , mais fournit également la relation spatiale entre une mémoire tampon de sortie de caméra et la surface de rendu.
Notez que, contrairement à la caméra, la propriété NativeOrientation n’est pas basée sur ACPI et n’a donc pas de structure _PLD. Cela est vrai même si un affichage est monté de manière statique sur un appareil.
Lors du montage sur un appareil principal Portrait, les pilotes d’appareil photo doivent savoir que la plupart des applications traitent l’appareil comme la sortie d’une mémoire tampon de sortie de caméra paysage, quelle que soit l’orientation réelle de la mémoire tampon de sortie de la caméra. Pour cette raison, nous recommandons que les pilotes d’appareil photo génèrent une mémoire tampon de caméra qui a un décalage d’orientation de 90 degrés par rapport à NativeOrientation Portrait sur un appareil principal Portrait. Cela permettra ensuite aux applications qui effectuent cette rotation supplémentaire sur les appareils portrait de corriger la rotation à l’orientation attendue. Cela peut être vérifié à l’aide de l’application Caméra avec l’exemple de rotation.
Montage de décalage
Les IHV/OEM sont vivement encouragés à éviter de monter le capteur dans un décalage non de 0 degré pour maintenir la compatibilité des applications. De nombreuses applications existantes et héritées ne savent pas rechercher la table PLD de l’ACPI, ni tenteront de corriger le décalage non de 0 degré. Par conséquent, pour ces applications, la vidéo résultante est rendue incorrectement.
Dans les cas où les IHV/OEM ne peuvent pas monter le capteur dans une orientation de 0 degré, comme décrit ci-dessus, les étapes d’atténuation suivantes sont recommandées dans l’ordre de préférence :
Corrigez automatiquement l’orientation non 0 degré dans le pilote de caméra (en mode noyau avec le pilote de miniport de flux AV ou en mode utilisateur à l’aide d’un plug-in tel que MFT ou MFT0) afin que les images de sortie résultantes soient dans l’orientation de 0 degré.
Déclarez l’orientation non 0 degré via la balise FSSensorOrientation afin que le pipeline d’appareil photo puisse corriger l’image capturée.
Déclarez l’orientation autre que 0 degré dans la table PLD de l’ACPI, comme décrit ci-dessus.
Types de médias compressés/encodés
Pour les types de médias compressés et/ou encodés (tels que MJPG, JPEG, H264, HEVC), le pipeline correct ne peut pas être utilisé. Pour cette raison, les types de médias compressés/encodés sont filtrés si FSSensorOrientation est défini sur une valeur autre que zéro.
Dans le cas des types de supports MJPG (comme ceux d’une caméra UVC), le pipeline Frame Server fournit un type de média décodé automatiquement (NV12 ou YUY2 pour les applications basées sur DShow). Le type de média automatiquement décodé et corrigé sera présenté, mais pas le format MJPG d’origine.
[! REMARQUE !] Si les types de média compressés/encodés doivent être exposés aux applications, les IHV/ODM ne doivent pas utiliser la correction FSSensorOrientation. Au lieu de cela, la correction doit être effectuée par le pilote de la caméra (soit en mode noyau via le pilote av Stream, soit en mode utilisateur via DMFT/MFT0).
Correction automatique via AV Stream Miniport/Appareil MFT/MFT0
Le scénario recommandé si les capteurs ne peuvent pas être montés avec un décalage de 0 degré, consiste à faire en sorte que le pilote de miniport av Stream (ou les plug-ins en mode utilisateur sous la forme de DMFT ou MFT0) corrigent le cadre capturé résultant afin qu’il soit exposé au pipeline dans un décalage de 0 degré.
Lors de la correction de l’image vidéo à partir du miniport av Stream et/ou du plug-in MFT/MFT0 de l’appareil, la déclaration de type de média obtenue doit être basée sur l’image corrigée. Si le capteur est monté à un décalage de 90 degrés de sorte que la vidéo obtenue est de 9 :16 proportions par rapport au capteur, mais que la vidéo corrigée est 16 :9, le type de média doit déclarer le format 16 :9.
Cela inclut les informations de progression obtenues. Cela est nécessaire, car le composant responsable de la correction est contrôlé par l’IHV/OEM et le pipeline de la caméra n’a pas de visibilité dans l’image vidéo, sauf après sa correction.
Il est vivement recommandé que la correction soit effectuée en mode utilisateur et que le contrat d’API entre le pipeline et le plug-in en mode utilisateur doit être suivi. Plus précisément, lors de l’utilisation de DMFT ou MFT0, lorsque IMFDeviceTransform ::P rocessMessage ou IMFTransform ::P rocessMessage est appelé avec un message MFT_MESSAGE_SET_D3D_MANAGER, le plug-in en mode utilisateur doit respecter les recommandations suivantes :
- Si aucun gestionnaire D3D n’est fourni (l’ulParam du message est 0), le plug-in en mode utilisateur ne doit PAS appeler d’opérations GPU pour gérer la correction de rotation. Et le frame obtenu doit être fourni dans la mémoire système.
- Si le gestionnaire D3D est fourni (l’ulParam du message est l’IUnknown d’un gestionnaire DXGI), ce gestionnaire DXGI doit être utilisé pour la correction de rotation et le frame obtenu doit être de la mémoire GPU.
- Le plug-in en mode utilisateur doit également gérer le message du gestionnaire D3D pendant l’exécution. Lorsque le message MFT_MESSAGE_SET_D3D_MANAGER est émis, la trame suivante produite par le plug-in doit correspondre au type de mémoire demandé (par exemple, GPU si DXGI Manager a été fourni, processeur dans le cas contraire).
- Lorsque le pilote de Stream AV (ou le plug-in en mode utilisateur) gère la correction de rotation, le champ Rotation de la structure PLD de l’ACPI doit être défini sur 0.
Notes
Lorsque la correction automatique est utilisée, les fabricants OEM et les IVS ne doivent PAS publier l’orientation réelle du capteur via le champ rotation _PLD. Dans ce cas, le champ Rotation doit indiquer l’orientation après la correction : 0 degré.
Déclarer via FSSensorOrientation
; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270
En déclarant l’orientation non de 0 degré du capteur via la balise de Registre FSSensorOrientation, le pipeline de caméra peut corriger la trame capturée avant de la présenter à l’application.
Le pipeline optimise la logique de rotation en tirant parti des ressources GPU ou PROCESSEUR en fonction du cas d’usage et de la demande/scénario de l’application.
ACPI PLD Rotation
Le champ Rotation de la structure PLD ACPI doit être 0. Cela permet d’éviter toute confusion dans les applications qui peuvent utiliser les informations PLD pour corriger le cadre.
Informations sur le type de média
Le type de média présenté par le pilote doit être le type de média non corrigée. Lorsque vous informez le pipeline de caméra du décalage non de 0 degré à l’aide de l’entrée FSSensorOrientation, les informations de type de média présentées par le capteur doivent être le type de média non corrigée. Par exemple, si le capteur est monté à 90 degrés de décalage dans le sens des aiguilles d’une montre, donc au lieu de proportions 16 :9, la vidéo obtenue est 9 :16, le type de média de proportions 9 :16 doit être présenté au pipeline de la caméra.
Cela est nécessaire pour s’assurer que le pipeline peut configurer correctement le processus de rotation des compteurs : le pipeline a besoin du type de média d’entrée et du type de média de sortie souhaité de l’application.
Cela inclut les informations sur les foulées. Les informations de foulée doivent être présentées pour le type de média non corrigée dans le pipeline de caméra.
Sous-clé de Registre
L’entrée de Registre FSSensorOrientation doit être publiée sur le nœud Device Interface. L’approche recommandée consiste à déclarer cela en tant que directive AddReg lors de la déclaration de directive AddInterface dans l’INF du pilote de caméra.
Les données présentées dans FSSensorOrientation doivent être une REG_DWORD et les seules valeurs valides acceptées seront 90, 180 et 270. Toute autre valeur est traitée comme décalage de 0 degré (c’est-à-dire ignorée).
Chaque valeur représente l’orientation du capteur en degrés dans le sens des aiguilles d’une montre. Le pipeline de caméra corrige l’image vidéo obtenue en faisant pivoter la vidéo de la même quantité dans le sens des aiguilles d’une montre : c’est-à-dire qu’une déclaration de 90 degrés dans le sens des aiguilles d’une montre entraîne une rotation de 90 degrés dans le sens inverse des aiguilles d’une montre pour ramener l’image vidéo résultante à un décalage de 0 degré.
Descriptor MS OS 1.0
Pour les caméras basées sur USB, FSSensorOrientation peut également être publié via des descripteurs MSOS.
MS OS Descriptor 1.0 a deux composants :
- Section d’en-tête de longueur fixe
- Une ou plusieurs sections de propriétés personnalisées de longueur variable, qui suivent la section d’en-tête
Section d’en-tête MS OS DESCRIPTOR 1.0
La section En-tête décrit une seule propriété personnalisée (Profil d’authentification visage).
Offset | Champ | Taille (en octets) | Valeur | Description |
---|---|---|---|---|
0 | dwLength | 4 | <> | |
4 | bcdVersion | 2 | 0x0100 | Version 1.0 |
6 | Windex | 2 | 0x0005 | Descripteur de système d’exploitation de propriété étendue |
8 | wCount | 2 | 0x0001 | Une propriété personnalisée |
Section de propriété MS OS DESCRIPTOR 1.0 personnalisée
Offset | Champ | Taille (en octets) | Valeur | Description |
---|---|---|---|---|
0 | dwSize | 4 | 0x00000036 (54) | Taille totale (en octets) de cette propriété. |
4 | dwPropertyDataType | 4 | 0x00000004 | REG_DWORD_LITTLE_ENDIAN |
8 | wPropertyNameLength | 2 | 0x00000024 (36) | Taille (en octets) du nom de la propriété. |
10 | bPropertyName | 50 | UVC-FSSensorOrientation | Chaîne « UVC-FSSensorOrientation » en Unicode. |
60 | dwPropertyDataLength | 4 | 0x00000004 | 4 octets pour les données de propriété (sizeof(DWORD)). |
64 | bPropertyData | 4 | Angle de décalage en degrés dans le sens des aiguilles d’une montre. | Les valeurs valides sont 90, 180 et 270. |
Ms OS Descriptor 2.0
MsOS Extended Descriptor 2.0 peut être utilisé pour définir les valeurs de Registre afin d’ajouter la prise en charge de FSSensorOrientation. Cette opération est effectuée à l’aide du descripteur de propriété de registre Microsoft OS 2.0.
Pour l’entrée de Registre UVC-FSSensorOrientation, voici un exemple de jeu de descripteur 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)
}
Déclarer via les informations PLD ACPI
En dernier recours, les informations PLD peuvent être exploitées comme décrit ci-dessus pour indiquer à l’application que la trame vidéo doit être corrigée avant d’être rendue/encodée. Toutefois, comme indiqué, de nombreuses applications existantes n’utilisent pas les informations PLD et ne gèrent pas la rotation des images, de sorte qu’il existe des scénarios où les applications peuvent ne pas être en mesure de restituer correctement la vidéo résultante.
Les illustrations suivantes illustrent les valeurs du champ rotation _PLD pour chaque configuration matérielle :
Rotation : 0 degré dans le sens des aiguilles d’une montre
Dans la figure ci-dessus :
L’image de gauche illustre la scène à capturer.
L’image du milieu montre comment une scène est affichée par un capteur CMOS dont l’ordre de lecture physique commence à partir du coin inférieur gauche et se déplace de gauche à droite vers le haut.
L’image à droite représente la sortie du pilote de l’appareil photo. Dans cet exemple, le contenu de la mémoire tampon multimédia peut être rendu directement tandis que l’affichage est son orientation native sans rotation supplémentaire. Par conséquent, le champ AcpI _PLD Rotation a une valeur de 0.
Rotation : 90 degrés dans le sens des aiguilles d’une montre
Dans ce cas, le contenu de la mémoire tampon multimédia est pivoté de 90 degrés dans le sens des aiguilles d’une montre par rapport à la scène d’origine. Par conséquent, le champ AcpI _PLD Rotation a une valeur de 2.
Rotation : 180 degrés dans le sens des aiguilles d’une montre
Dans ce cas, le contenu de la mémoire tampon multimédia est pivoté de 180 degrés dans le sens des aiguilles d’une montre par rapport à la scène d’origine. Par conséquent, le champ AcpI _PLD Rotation a une valeur de 4.
Rotation : 270 degrés dans le sens des aiguilles d’une montre
Dans ce cas, le contenu de la mémoire tampon multimédia est pivoté de 270 degrés dans le sens des aiguilles d’une montre par rapport à la scène d’origine. Par conséquent, le champ ACPI _PLD Rotation a la valeur 6.