Suporte ao driver para orientação da câmera
Importante
O método de correção automática discutido posteriormente neste tópico é a solução recomendada para a montagem de orientação não referenciada de sensores de câmera. Isso é para garantir a compatibilidade do aplicativo, pois a maioria dos aplicativos já gravados para usar feeds de câmera não sabe marcar para, nem correto para obter informações de rotação. Examine cuidadosamente as informações na seção corrigir automaticamente abaixo.
À medida que diferentes fatores de forma que os dispositivos de computação são introduzidos, algumas das restrições físicas resultam na montagem de sensores de câmera em uma orientação não tradicional. Por isso, é necessário descrever corretamente para o sistema operacional e o aplicativo, como os sensores são montados para que o vídeo resultante possa ser renderizado/gravado corretamente.
A partir da Janela 10, versão 1607, todos os drivers de câmera são necessários para especificar explicitamente a orientação da câmera, independentemente de a câmera estar montada de acordo com os requisitos mínimos de hardware. Especificamente, um driver de câmera deve definir um campo recém-introduzido, Rotation, na estrutura de _PLD ACPI associada a uma interface do 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 a câmera, o campo Rotação em uma estrutura de _PLD ACPI especifica o número de graus ('0' para 0°, '2' para 90°, '4' para 180°e '6' para 270°) um quadro capturado é girado em relação à tela enquanto o vídeo está em sua orientação nativa.
Com base no valor no campo Rotação , um aplicativo pode executar rotação adicional, se necessário, para renderizar os quadros capturados corretamente.
Valores de rotação
Para aqueles dispositivos cujas câmeras e telas compartilham a mesma habitação (ouinvólucro de compartimento/), é possível que esses periféricos sejam montados em diferentes superfícies com cada um deles sendo girados por um grau fixo, mas arbitrário em seu respectivo plano. Consequentemente, um aplicativo precisa de um mecanismo para descrever a relação espacial entre os dois periféricos de modo que um quadro capturado possa ser transposto para a superfície de renderização na orientação correta.
Uma maneira de resolver o problema é usar o ACPI _PLD estrutura que já tem os conceitos de superfície e graus de rotação definidos . Por exemplo, a estrutura _PLD já tem um campo de painel que especifica a superfície na qual reside um periférico:
Definição do campo Painel de _PLD ACPI (Rev. 5.0a)
Os próximos dois diagramas ilustram a definição de cada painel visualmente:
Definições de painel para computadores desktop e a maioria dos dispositivos
Definições de painel para dispositivos dobráveis
Na verdade, o conceito de um "painel" de ACPI já é adotado pelo Windows em que:
Uma interface do dispositivo de câmera é associada a uma estrutura _PLD com o campo Painel sendo definido de acordo se um dispositivo de captura for montado estaticamente em um local fixo.
Um aplicativo pode recuperar o painel no qual um dispositivo de captura reside chamando a propriedade Windows.Devices.Enumeration.DeviceInformation.EnclosureLocation.Panel .
A estrutura de _PLD acpi também tem um campo rotação definido da seguinte maneira:
Definição do campo rotação de _PLD ACPI (Rev 5.0a)
Em vez de usar a definição acima como está, refinamos-a ainda mais para evitar ambiguidade:
- Para a câmera, o campo Rotação em uma estrutura de _PLD ACPI especifica o número de graus ('0' para 0°, '2' para 90°, '4' para 180°e '6' para 270°) um quadro capturado é girado em relação à tela enquanto o vídeo está em sua orientação nativa.
Paisagem Primária versus Retrato Primário
No Windows, é possível consultar a orientação de exibição nativa chamando a propriedade Windows.Graphics.Display.DisplayInformation.NativeOrientation, que retorna Paisagem ou Retrato:
Não importa qual valor NativeOrientation retorne, o padrão de verificação de exibição lógica começa no canto superior esquerdo da tela movendo-se da esquerda para a direita para baixo (consulte Figura 5). Para os dispositivos cuja orientação física padrão é inexplicit, essa propriedade não apenas implica o local de um painel superior acpi, mas também fornece a relação espacial entre um buffer de saída da câmera e a superfície de renderização.
Observe que, ao contrário da câmera, a propriedade NativeOrientation não é baseada em ACPI e, portanto, não tem uma estrutura _PLD. Isso é verdadeiro mesmo se uma exibição for montada estaticamente em um dispositivo.
Ao montar em um dispositivo Retrato Primário, os drivers de câmera devem estar cientes de que a maioria dos aplicativos tratará o dispositivo como saída de um buffer de saída de câmera paisagem, independentemente da orientação real do buffer de saída da câmera. Por isso, recomendamos que os drivers de câmera gerem um buffer de câmera que tenha um deslocamento de orientação de 90 graus do NativeOrientation Portrait quando estiver em um dispositivo Portrait Primary. Em seguida, isso permitirá que os aplicativos que estão executando essa rotação adicional em dispositivos retrato corrijam a rotação para a orientação esperada. Isso pode ser verificado usando o Aplicativo de Câmera com Amostra de Rotação.
Montagem de deslocamento
Os IHV/OEMs são fortemente incentivados a evitar a montagem do sensor em um deslocamento de não 0 graus para manter a compatibilidade do aplicativo. Muitos aplicativos existentes e herdados não sabem procurar a tabela PLD do ACPI nem tentarão corrigir o deslocamento de não 0 graus. Consequentemente, para esses aplicativos, o vídeo resultante será renderizado incorretamente.
Nos casos em que os IHV/OEMs não conseguem montar o sensor na orientação de 0 grau, conforme descrito acima, as seguintes etapas de mitigação são recomendadas na ordem de preferência:
Corrija automaticamente a orientação de não 0 grau no Driver da Câmera (no modo kernel com o driver de miniporto de fluxo AV ou no modo de usuário usando um plug-in como o Dispositivo MFT ou MFT0) para que os quadros de saída resultantes estejam na orientação de 0 grau.
Declare a orientação não 0 grau por meio da marca FSSensorOrientation para que o Pipeline da Câmera possa corrigir a imagem capturada.
Declare a orientação não 0 grau na tabela PLD do ACPI, conforme descrito acima.
Tipos de mídia compactados/codificados
Para tipos de mídia compactados e/ou codificados (como MJPG, JPEG, H264, HEVC), o pipeline correto não pode ser usado. Por isso, os Tipos de Mídia Compactados/Codificados serão filtrados se fSSensorOrientation for definido como um valor diferente de zero.
No caso de tipos de mídia MJPG (como os de uma câmera UVC), o pipeline do Frame Server fornece um tipo de mídia decodificado automaticamente (NV12 ou YUY2 para aplicativos baseados em DShow). O tipo de mídia autocodificada e corrigida será apresentado, mas o formato MJPG original não será.
[! OBSERVAÇÃO!] Se tipos de mídia compactados/codificados precisarem ser expostos a aplicativos, IHV/ODMs não deverão utilizar a correção FSSensorOrientation. Em vez disso, a correção deve ser feita pelo driver da câmera (no modo kernel por meio do driver de Stream AV ou no modo de usuário via DMFT/MFT0).
Correção automática por meio do AV Stream Miniport/Device MFT/MFT0
O cenário recomendado se os sensores não puderem ser montados com um deslocamento de 0 grau é ter o driver de miniporto AV Stream (ou os plug-ins do modo de usuário na forma de DMFT ou MFT0) corrigir o quadro capturado resultante para que ele seja exposto ao pipeline em um deslocamento de 0 grau.
Ao corrigir o quadro de vídeo do AV Stream Miniport e/ou o plug-in MFT/MFT0 do dispositivo, a declaração de tipo de mídia resultante deve ser baseada no quadro corrigido. Se o sensor estiver montado em um deslocamento de 90 graus para que o vídeo resultante seja a taxa de proporção de 9:16 do sensor, mas o vídeo corrigido for 16:9, o tipo de mídia deverá declarar a taxa de proporção 16:9.
Isso inclui as informações de passo resultantes. Isso é necessário, pois o componente responsável por fazer a correção é controlado pelo IHV/OEM e o pipeline da câmera não tem visibilidade do quadro de vídeo, exceto depois de ter sido corrigido.
É altamente incentivado que a correção seja feita no modo de usuário e o contrato de API entre o pipeline e o plug-in do modo de usuário deve ser seguido. Especificamente, ao usar o DMFT ou o MFT0, quando IMFDeviceTransform::P rocessMessage ou IMFTransform::P rocessMessage é invocado com uma mensagem MFT_MESSAGE_SET_D3D_MANAGER, o plug-in do modo de usuário deve seguir as seguintes diretrizes:
- Se nenhum gerenciador D3D for fornecido (o ulParam da mensagem for 0), o plug-in do modo de usuário NÃO deverá invocar nenhuma operação de GPU para lidar com a correção de rotação. E o quadro resultante deve ser fornecido na memória do sistema.
- Se o gerenciador D3D for fornecido (o ulParam da mensagem é o IUnknown de um Gerenciador DXGI), esse Gerenciador de DXGI deverá ser usado para correção de rotação e o quadro resultante deve ser memória de GPU.
- O plug-in do modo de usuário também deve lidar com a mensagem do gerenciador D3D durante o runtime. Quando a mensagem MFT_MESSAGE_SET_D3D_MANAGER for emitida, o próximo quadro produzido pelo plug-in deverá corresponder ao tipo de memória solicitado (ou seja, GPU se o Gerenciador de DXGI tiver sido fornecido, caso contrário, a CPU).
- Quando o driver de Stream do AV (ou o plug-in do modo de usuário) manipula a correção de rotação, o campo Rotação da estrutura PLD da ACPI deve ser definido como 0.
Observação
Quando o Auto Correct é usado, os OEMs e os IHVs NÃO devem anunciar a orientação real do sensor por meio do campo rotação de _PLD. Nesse caso, o campo Rotação deve indicar a orientação após a correção: 0 graus.
Declarar via FSSensorOrientation
; Defines the sensor mounting orientation offset angle in
; degrees clockwise.
FSSensorOrientation: REG_DWORD: 90, 180, 270
Ao declarar a orientação não 0 grau do sensor por meio da marca do registro FSSensorOrientation, o pipeline da câmera pode corrigir o quadro capturado antes de apresentá-lo ao aplicativo.
O pipeline otimizará a lógica de rotação aproveitando os recursos de GPU ou CPU com base no caso de uso e na solicitação/cenário do aplicativo.
Rotação de PLD do ACPI
O campo Rotação da estrutura PLD do ACPI deve ser 0. Isso é para evitar aplicativos confusos que podem usar as informações de PLD para corrigir o quadro.
Informações de tipo de mídia
O Tipo de Mídia apresentado pelo driver deve ser o tipo de mídia não corrigido. Ao informar o pipeline da câmera do deslocamento de não 0 grau usando a entrada FSSensorOrientation, as informações de tipo de mídia apresentadas pelo sensor devem ser o tipo de mídia não corrigido. Por exemplo, se o sensor estiver montado 90 graus no sentido horário, portanto, em vez da taxa de proporção de 16:9, o vídeo resultante for 9:16, o tipo de mídia de taxa de proporção 9:16 deverá ser apresentado ao pipeline da câmera.
Isso é necessário para garantir que o pipeline possa configurar corretamente o processo de contra-rotação: o pipeline precisa do tipo de mídia de entrada e do tipo de mídia de saída desejado do aplicativo.
Isso inclui as informações de passo a passo. As informações passo a passo devem ser apresentadas para o tipo de mídia não corrigido para o pipeline da câmera.
Subchave do registro
A entrada do registro FSSensorOrientation deve ser publicada no nó Interface do Dispositivo. A abordagem recomendada é declarar isso como uma diretiva AddReg durante a declaração de diretiva AddInterface no INF do driver de câmera.
Os dados apresentados no FSSensorOrientation devem ser um REG_DWORD e os únicos valores válidos aceitos serão 90, 180 e 270. Qualquer outro valor será tratado como deslocamento de 0 graus (ou seja, ignorado).
Cada valor representa a orientação do sensor em graus no sentido horário. O pipeline da câmera corrigirá o quadro de vídeo resultante ao girar o vídeo pela mesma quantidade no sentido anti-horário: ou seja, uma declaração no sentido horário de 90 graus resultará em uma rotação anti-horário de 90 graus para trazer o quadro de vídeo resultante de volta para deslocamento de 0 grau.
Descritor do SISTEMA OPERACIONAL MS 1.0
Para câmeras baseadas em USB, FSSensorOrientation também pode ser publicado por meio de descritores MSOS.
O Ms OS Descriptor 1.0 tem dois componentes:
- Uma seção de cabeçalho de comprimento fixo
- Uma ou mais seções de propriedades personalizadas de comprimento variável, que segue a seção de cabeçalho
Seção de cabeçalho DO MS OS DESCRIPTOR 1.0
A Seção Cabeçalho descreve uma única propriedade personalizada (Face Auth Profile).
Deslocamento | Campo | Tamanho (bytes) | Valor | Descrição |
---|---|---|---|---|
0 | dwLength | 4 | <> | |
4 | bcdVersion | 2 | 0x0100 | Versão 1.0 |
6 | Windex | 2 | 0x0005 | Descritor de sistema operacional de propriedade estendida |
8 | wCount | 2 | 0x0001 | Uma propriedade personalizada |
Seção de propriedade PERSONALIZADA DO MS OS DESCRIPTOR 1.0
Deslocamento | Campo | Tamanho (bytes) | Valor | Descrição |
---|---|---|---|---|
0 | dwSize | 4 | 0x00000036 (54) | Tamanho total (em bytes) para essa propriedade. |
4 | dwPropertyDataType | 4 | 0x00000004 | REG_DWORD_LITTLE_ENDIAN |
8 | wPropertyNameLength | 2 | 0x00000024 (36) | Tamanho (em bytes) do nome da propriedade. |
10 | bPropertyName | 50 | UVC-FSSensorOrientation | Cadeia de caracteres "UVC-FSSensorOrientation" em Unicode. |
60 | dwPropertyDataLength | 4 | 0x00000004 | 4 bytes para dados de propriedade (sizeof(DWORD)). |
64 | bPropertyData | 4 | Ângulo de deslocamento em graus no sentido horário. | Os valores válidos são 90, 180 e 270. |
Descritor do SISTEMA OPERACIONAL MS 2.0
O Descritor Estendido do MSOS 2.0 pode ser usado para definir os valores do Registro para adicionar suporte a FSSensorOrientation. Isso é feito usando o Descritor de Propriedade do Registro do Microsoft OS 2.0.
Para a entrada do registro UVC-FSSensorOrientation, o seguinte mostra um exemplo de conjunto de descritores do 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)
}
Declarar por meio de informações pld acpi
Como uma opção de último recurso, as informações de PLD podem ser aproveitadas conforme descrito acima para indicar ao aplicativo que o quadro de vídeo deve ser corrigido antes de ser renderizado/codificado. No entanto, como mencionado, muitos aplicativos existentes não usam as informações pld nem lidam com a rotação de quadros, portanto, haverá cenários em que os aplicativos podem não ser capazes de renderizar o vídeo resultante corretamente.
As seguintes figuras ilustram os valores do campo Rotação de _PLD para cada configuração de hardware:
Rotação: 0 grau no sentido horário
Na figura acima:
A imagem à esquerda ilustra a cena a ser capturada.
A imagem no meio mostra como uma cena é exibida por um sensor CMOS cuja ordem de leitura física começa do canto inferior esquerdo movendo-se da esquerda para a direita para cima.
A imagem à direita representa a saída do driver da câmera. Neste exemplo, o conteúdo do buffer de mídia pode ser renderizado diretamente enquanto a exibição é sua orientação nativa sem rotação adicional. Consequentemente, o campo Rotação de _PLD ACPI tem um valor de 0.
Rotação: 90 graus no sentido horário
Nesse caso, o conteúdo do buffer de mídia é girado em 90 graus no sentido horário em comparação com a cena original. Como resultado, o campo Rotação de _PLD ACPI tem um valor de 2.
Rotação: 180 graus no sentido horário
Nesse caso, o conteúdo do buffer de mídia é girado em 180 graus no sentido horário em comparação com a cena original. Como resultado, o campo Rotação de _PLD ACPI tem um valor de 4.
Rotação: 270 graus no sentido horário
Nesse caso, o conteúdo do buffer de mídia é girado em 270 graus no sentido horário em comparação com a cena original. Como resultado, o campo Rotação de _PLD ACPI tem um valor de 6.