Compatibilidad con controladores para la orientación de la cámara
Importante
El método autocorrección descrito más adelante en este tema es la solución recomendada para el montaje de orientación no de referencia de los sensores de cámara. Esto es para garantizar la compatibilidad de la aplicación, ya que la mayoría de las aplicaciones ya escritas para usar fuentes de cámara no saben comprobar la información de rotación ni corregirla. Revise detenidamente la información de la sección autocorrección siguiente.
A medida que se introducen diferentes factores de forma, algunas de las restricciones físicas dan lugar a que los sensores de cámara se monten en una orientación no tradicional. Por este motivo, es necesario describir correctamente el sistema operativo y la aplicación, cómo se montan los sensores para que el vídeo resultante se pueda representar o grabar correctamente.
A partir de la ventana 10, versión 1607, todos los controladores de cámara deben especificar explícitamente la orientación de la cámara, independientemente de si la cámara está montada de acuerdo con los requisitos mínimos de hardware. En concreto, un controlador de cámara debe establecer un campo recién introducido, Rotación, en la estructura de _PLD ACPI asociada a una interfaz de dispositivo de captura:
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;
Para la cámara, el campo Rotación en una estructura ACPI _PLD especifica el número de grados ('0' para 0°, '2' para 90°, '4' para 180°, y '6' para 270°) un marco capturado se gira en relación con la pantalla mientras la pantalla está en su orientación nativa.
En función del valor del campo Rotación , una aplicación puede realizar una rotación adicional, si es necesario, para representar los fotogramas capturados correctamente.
Valores de rotación
Para aquellos dispositivos cuyas cámaras y pantallas comparten la misma carcasa (o/ carcasa), es posible montar estos periféricos en diferentes superficies con cada uno de ellos girando por un grado fijo pero arbitrario en su plano respectivo. Por lo tanto, una aplicación necesita un mecanismo para describir la relación espacial entre los dos periféricos de forma que un marco capturado se pueda transponer a la superficie de representación en la orientación correcta.
Una manera de resolver el problema es usar la estructura de _PLD ACPI que ya tiene los conceptos de superficie y grados de rotación definidos. Por ejemplo, la estructura _PLD ya tiene un campo de panel que especifica la superficie en la que reside un periférico:
Definición del campo AcpI _PLD Panel (Rev. 5.0a)
Los dos diagramas siguientes muestran la definición de cada panel visualmente:
Definiciones de panel para equipos de escritorio y la mayoría de los dispositivos
Definiciones de panel para dispositivos plegables
De hecho, Windows ya ha adoptado el concepto de un "panel ACPI" en el que:
Una interfaz de dispositivo de cámara está asociada a una estructura de _PLD con el campo Panel que se establece en consecuencia si un dispositivo de captura está montado estáticamente en una ubicación fija.
Una aplicación puede recuperar el panel en el que reside un dispositivo de captura llamando a la propiedad Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .
La estructura _PLD ACPI también tiene un campo Rotación definido como sigue:
Definición del campo de rotación de _PLD ACPI (Rev 5.0a)
En lugar de usar la definición anterior tal cual, se refina aún más para evitar ambigüedad:
- Para la cámara, el campo Rotación de una estructura ACPI _PLD especifica el número de grados ('0' para 0°, '2' para 90°, '4' para 180°, y '6' para 270°) un marco capturado gira en relación con la pantalla mientras la pantalla está en su orientación nativa.
Horizontal principal frente a principal vertical
En Windows, puede consultar la orientación de visualización nativa llamando a la propiedad Windows.Graphics.Display.DisplayInformation.NativeOrientation, que devuelve Horizontal o Vertical:
Independientemente del valor que devuelva NativeOrientation , el patrón de examen de visualización lógico comienza desde la esquina superior izquierda de la pantalla que se mueve de izquierda a derecha hacia abajo (vea la figura 5). Para aquellos dispositivos cuya orientación física predeterminada es inexplicit, esta propiedad no solo implica la ubicación de un panel superior ACPI, sino que también proporciona la relación espacial entre un búfer de salida de la cámara y la superficie de representación.
Tenga en cuenta que, a diferencia de la cámara, la propiedad NativeOrientation no se basa en ACPI y, por tanto, no tiene una estructura _PLD. Esto es true incluso si una pantalla está montada estáticamente en un dispositivo.
Al montar en un dispositivo vertical principal, los controladores de cámara deben tener en cuenta que la mayoría de las aplicaciones tratarán al dispositivo como la salida de un búfer de salida de cámara horizontal independientemente de la orientación real del búfer de salida de la cámara. Por este motivo, se recomienda que los controladores de cámara produzcan un búfer de cámara que tenga un desplazamiento de orientación de 90 grados desde el retrato NativeOrientation cuando se encuentra en un dispositivo primario vertical. A continuación, permitirá que las aplicaciones que realicen esta rotación adicional en dispositivos verticales corrijan la rotación a la orientación esperada. Esto se puede comprobar mediante la aplicación de cámara con el ejemplo de rotación.
Montaje de desplazamiento
Se recomienda encarecidamente que IHV/OEMs evite montar el sensor en un desplazamiento que no sea de 0 grados para mantener la compatibilidad de la aplicación. Muchas aplicaciones existentes y heredadas no saben buscar la tabla PLD de ACPI, ni intentarán corregir el desplazamiento no 0 grados. Por lo tanto, para estas aplicaciones, el vídeo resultante se representará incorrectamente.
En los casos en los que los IHV/OEM no pueden montar el sensor en orientación de 0 grados, como se ha descrito anteriormente, se recomiendan los siguientes pasos de mitigación en el orden de preferencia:
Corrija automáticamente la orientación no 0 grados dentro del controlador de cámara (ya sea en modo kernel con el controlador de miniporte av o en modo de usuario mediante un complemento como Device MFT o MFT0) para que los fotogramas de salida resultantes estén en la orientación de 0 grados.
Declare la orientación no 0 grados a través de la etiqueta FSSensorOrientation para que la canalización de cámara pueda corregir la imagen capturada.
Declare la orientación no 0 grados en la tabla PLD de ACPI como se ha descrito anteriormente.
Tipos de medios comprimidos o codificados
Para los tipos de medios comprimidos o codificados (como MJPG, JPEG, H264, HEVC), no se puede usar la canalización correcta. Por este motivo, los tipos de medios comprimidos o codificados se filtrarán si FSSensorOrientation está establecido en un valor distinto de cero.
En el caso de los tipos de medios MJPG (como los de una cámara UVC), la canalización de Frame Server proporciona un tipo de medio descodificado automáticamente (NV12 o YUY2 para aplicaciones basadas en DShow). Se mostrará el tipo de medio descodificado y corregido automáticamente, pero el formato MJPG original no lo hará.
[! NOTA!] Si los tipos de medios comprimidos o codificados deben exponerse a las aplicaciones, los IHV/ODMs no deben utilizar la corrección FSSensorOrientation. En su lugar, el controlador de cámara debe realizar la corrección (ya sea en modo kernel a través del controlador av Stream o en modo de usuario a través de DMFT/MFT0).
Corrección automática a través de AV Stream Miniport/Device MFT/MFT0
El escenario recomendado si los sensores no se pueden montar con un desplazamiento de 0 grados, es hacer que el controlador de miniporte av Stream (o el modo de usuario conecta en forma de DMFT o MFT0) corrija el marco capturado resultante para que se exponga a la canalización en un desplazamiento de 0 grados.
Al corregir el fotograma de vídeo de la Stream AV Miniport o el complemento Device MFT/MFT0, la declaración de tipo multimedia resultante debe basarse en el marco corregido. Si el sensor está montado en un desplazamiento de 90 grados para que el vídeo resultante sea la relación de aspecto 9:16 del sensor, pero el vídeo corregido sería 16:9, el tipo de medio debe declarar la relación de aspecto 16:9.
Esto incluye la información de paso resultante. Esto es necesario, ya que el componente responsable de realizar la corrección está controlado por el IHV/OEM y la canalización de la cámara no tiene visibilidad en el fotograma de vídeo, excepto después de que se haya corregido.
Se recomienda encarecidamente que se realice la corrección en modo de usuario y que se debe seguir el contrato de API entre la canalización y el complemento de modo de usuario. En concreto, cuando se usa dmft o MFT0, cuando el IMFDeviceTransform::P rocessMessage o IMFTransform::P rocessMessage se invoca con un mensaje MFT_MESSAGE_SET_D3D_MANAGER, el complemento de modo de usuario debe cumplir la siguiente guía:
- Si no se proporciona ningún administrador D3D (el ulParam del mensaje es 0), el complemento de modo de usuario NO debe invocar ninguna operación de GPU para controlar la corrección de rotación. Y el marco resultante debe proporcionarse en la memoria del sistema.
- Si se proporciona el administrador D3D (el ulParam del mensaje es IUnknown de un administrador DXGI), ese Administrador DXGI debe usarse para la corrección de rotación y el marco resultante debe ser memoria gpu.
- El complemento de modo de usuario también debe controlar el mensaje del administrador D3D durante el tiempo de ejecución. Cuando se emite el mensaje de MFT_MESSAGE_SET_D3D_MANAGER, el siguiente fotograma generado por el complemento debe corresponder al tipo de memoria solicitado (es decir, GPU si se proporcionó DXGI Manager, CPU en caso contrario).
- Cuando el controlador de Stream av (o el complemento de modo de usuario) controla la corrección de rotación, el campo Rotación de la estructura PLD de la ACPI debe establecerse en 0.
Nota
Cuando se usa Auto Correct, los OEM e IHD NO deben anunciar la orientación real del sensor a través del campo Rotación de _PLD. En este caso, el campo Rotación debe indicar la orientación después de la corrección: 0 grados.
Declarar a través de FSSensorOrientation
; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270
Al declarar la orientación no 0 grados del sensor a través de la etiqueta del registro FSSensorOrientation, la canalización de la cámara puede corregir el fotograma capturado antes de presentarlo a la aplicación.
La canalización optimizará la lógica de rotación aprovechando los recursos de GPU o CPU en función del caso de uso y la solicitud o escenario de la aplicación.
Rotación de PLD ACPI
El campo Rotación de la estructura PLD ACPI debe ser 0. Esto es para evitar aplicaciones confusas que pueden usar la información de PLD para corregir el fotograma.
Información de tipo de medio
El tipo de medio presentado por el controlador debe ser el tipo de medio no corregido. Al informar a la canalización de la cámara del desplazamiento que no es de 0 grados mediante la entrada FSSensorOrientation, la información de tipo multimedia presentada por el sensor debe ser el tipo de medio no corregido. Por ejemplo, si el sensor está montado 90 grados de desplazamiento en el sentido de las agujas del reloj, por lo que, en lugar de una relación de aspecto de 16:9, el vídeo resultante es 9:16, el tipo de medio de relación de aspecto 9:16 debe presentarse a la canalización de la cámara.
Esto es necesario para asegurarse de que la canalización puede configurar correctamente el proceso de rotación de contadores: la canalización necesita el tipo de medio de entrada y el tipo de medio de salida deseado de la aplicación.
Esto incluye la información de paso. La información de paso debe presentarse para el tipo de medio no corregido en la canalización de la cámara.
Subclave del Registro
La entrada del Registro FSSensorOrientation debe publicarse en el nodo Interfaz de dispositivo. El enfoque recomendado es declararlo como una directiva AddReg durante la declaración de directiva AddInterface en el INF del controlador de cámara.
Los datos presentados en FSSensorOrientation deben ser un REG_DWORD y los únicos valores válidos aceptados serán 90, 180 y 270. Cualquier otro valor se tratará como desplazamiento de 0 grados (es decir, omitido).
Cada valor representa la orientación del sensor en grados en el sentido de las agujas del reloj. La canalización de cámara corregirá el fotograma de vídeo resultante girando el vídeo por la misma cantidad en sentido contrario a las agujas del reloj: es decir, una declaración en sentido contrario a las agujas del reloj de 90 grados dará como resultado una rotación de las agujas del reloj de 90 grados para devolver el fotograma de vídeo resultante a un desplazamiento de 0 grados.
Descriptor de SO de MS 1.0
En el caso de las cámaras basadas en USB, FSSensorOrientation también se puede publicar a través de descriptores de MSOS.
MS OS Descriptor 1.0 tiene dos componentes:
- Sección de encabezado de longitud fija
- Una o varias secciones de propiedades personalizadas de longitud variable, que siguen la sección de encabezado
Sección del encabezado DESCRIPTOR 1.0 de MS OS
La sección Encabezado describe una única propiedad personalizada (Perfil de autenticación de Face).
Offset | Campo | Tamaño (bytes) | Valor | Descripción |
---|---|---|---|---|
0 | dwLength | 4 | <> | |
4 | bcdVersion | 2 | 0x0100 | Versión 1.0 |
6 | Windex | 2 | 0x0005 | Descriptor de so de propiedad extendida |
8 | wCount | 2 | 0x0001 | Una propiedad personalizada |
Sección de propiedades CUSTOM MS OS DESCRIPTOR 1.0
Offset | Campo | Tamaño (bytes) | Valor | Descripción |
---|---|---|---|---|
0 | dwSize | 4 | 0x00000036 (54) | Tamaño total (en bytes) para esta propiedad. |
4 | dwPropertyDataType | 4 | 0x00000004 | REG_DWORD_LITTLE_ENDIAN |
8 | wPropertyNameLength | 2 | 0x00000024 (36) | Tamaño (en bytes) del nombre de propiedad. |
10 | bPropertyName | 50 | UVC-FSSensorOrientation | Cadena "UVC-FSSensorOrientation" en Unicode. |
60 | dwPropertyDataLength | 4 | 0x00000004 | 4 bytes para los datos de propiedad (sizeof(DWORD)). |
64 | bPropertyData | 4 | Ángulo de desplazamiento en grados en el sentido de las agujas del reloj. | Los valores válidos son 90, 180 y 270. |
Ms OS Descriptor 2.0
MsOS Extended Descriptor 2.0 se puede usar para definir los valores del Registro para agregar compatibilidad con FSSensorOrientation. Esto se hace mediante el Descriptor de propiedad del Registro de Microsoft OS 2.0.
Para la entrada del Registro de UVC-FSSensorOrientation, a continuación se muestra un conjunto de descriptores de MSOS 2.0 de ejemplo:
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)
}
Declarar a través de la información de ACPI PLD
Como opción del último recurso, la información de PLD se puede aprovechar como se ha descrito anteriormente para indicar a la aplicación que el fotograma de vídeo debe corregirse antes de representarse o codificarse. Sin embargo, como se indica, muchas aplicaciones existentes no usan la información de PLD ni controlan la rotación de fotogramas, por lo que habrá escenarios en los que es posible que las aplicaciones no puedan representar correctamente el vídeo resultante.
En las ilustraciones siguientes se muestran los valores del campo Rotación de _PLD para cada configuración de hardware:
Rotación: 0 grados en el sentido de las agujas del reloj
En la ilustración anterior:
La imagen de la izquierda ilustra la escena que se va a capturar.
La imagen en el medio muestra cómo un sensor CMOS ve una escena cuyo orden físico de lectura comienza desde la esquina inferior izquierda que se mueve de izquierda a derecha hacia arriba.
La imagen de la derecha representa la salida del controlador de cámara. En este ejemplo, el contenido del búfer multimedia se puede representar directamente mientras la pantalla es su orientación nativa sin rotación adicional. Por lo tanto, el campo ACPI _PLD Rotación tiene un valor de 0.
Rotación: 90 grados en el sentido de las agujas del reloj
En este caso, el contenido del búfer multimedia gira en 90 grados en el sentido de las agujas del reloj en comparación con la escena original. Como resultado, el campo ACPI _PLD Rotación tiene un valor de 2.
Rotación: 180 grados en el sentido de las agujas del reloj
En este caso, el contenido del búfer multimedia gira en 180 grados en el sentido de las agujas del reloj en comparación con la escena original. Como resultado, el campo ACPI _PLD Rotación tiene un valor de 4.
Rotación: 270 grados en el sentido de las agujas del reloj
En este caso, el contenido del búfer multimedia gira en 270 grados en el sentido de las agujas del reloj en comparación con la escena original. Como resultado, el campo ACPI _PLD Rotación tiene un valor de 6.