Suporte à lanterna

A partir do Windows Threshold, vamos expor uma nova API de Lâmpada do WinRT que permite programar o flash de câmera sem a necessidade de criar uma instância de Windows.Media.Capture.MediaCapture. Ao fazer isso, um desenvolvedor pode escrever um aplicativo de lanterna (somente para fins de iluminação) utilizando a menor quantidade de recursos, incluindo energia, de modo que um dispositivo eletrônico possa ser otimizado para prolongar a vida útil da bateria e o desempenho.

Para isso, um IHV/OEM deve implementar um driver WDM que dê suporte às seguintes funções:

  • Permitir que o sistema enumere todos os dispositivos flash.

  • Ative/desative a lanterna por dispositivo.

  • Se aplicável, ajuste a intensidade da luz (semelhante ao PowerPercent) em uma base por dispositivo.

  • Se aplicável, especifique a cor clara por dispositivo.

Em termos de funcionalidade, a lista acima se sobrepõe significativamente à de MediaCapture (por exemplo, FlashControl e TorchControl). Além disso, o mesmo hardware flash está sendo usado para lâmpada e flash durante a captura. Consequentemente, recomenda-se que um IHV/OEM ofereça suporte a ambos os tipos de operações usando exclusivamente um único driver WDM para controlar o flash. A figura a seguir ilustra o conceito:

Diagrama do conceito de controle de flash exclusivo.

No exemplo acima, há apenas uma instância de hardware flash (mostrada como) e ela é gerenciada por um único driver flash KMDF. O driver flash expõe duas interfaces de dispositivo, cada uma delas direcionada para um tipo específico de cliente (ou a API do WinRT). Por exemplo, dada a figura acima:

  • A API MediaCapture do WinRT e o minidriver AVStream sempre se comunicam com o driver flash por meio da interface GUID_DEVINTERFACE_CAMERA_FLASH, enquanto

  • A API Lamp do WinRT sempre se comunica com o driver flash por meio da interface GUID_DEVINTERFACE_LAMP.

Como a interface GUID_DEVINTERFACE_CAMERA_FLASH é usada por um minidriver AVStream específico do fornecedor, um IHV/OEM tem liberdade para definir sua funcionalidade a seu critério — não são impostas restrições pelo Windows.

No entanto, a Microsoft padronizará a interface, GUID_DEVINTERFACE_LAMP, pois ela deve ser usada pela API de Lâmpada do WinRT. Para obter mais informações sobre GUID_DEVINTERFACE_LAMP, consulte o GUID da classe de interface do dispositivo

Casos de uso de concorrência

Compartilhando flash entre aplicativos de câmera e lanterna

Um flash de câmera normalmente é considerado como um periférico subordinado a um dispositivo de captura. Ele não deve ser compartilhado com cenários que não são de câmera enquanto a captura está em execução. Para complicar ainda mais, o número de dispositivos flash em um chassi é extremamente limitado, de modo que, na prática, não haverá flash sobressalente dedicado exclusivamente ao uso como lanterna.

Do ponto de vista do software, o acima impõe um desafio em que um aplicativo de câmera e um aplicativo de lanterna podem coexistir e acessar flash ao mesmo tempo. Por exemplo, em teoria, um usuário pode alternar o estado do LED por meio de um aplicativo de lanterna enquanto um visor de câmera está em execução.

Como a câmera requer controles precisos sobre o flash para dar suporte ao foco e à captura, pode ser difícil para o driver resolver solicitações flash de interesses conflitantes, garantindo a qualidade da imagem. Para resolver esse problema, a política a seguir é imposta no nível do sistema como um contrato:

  • Se uma sessão de captura for iniciada primeiro, um aplicativo de lanterna não poderá manipular flash até que a captura seja interrompida.

    • Um aplicativo de lanterna ainda pode adquirir um manipulador para o driver flash, mas qualquer operação que modifique o estado do flash gera um erro imediato.

    • Quando a captura é interrompida de forma que o minidriver AVStream libere o flash, é necessário que o driver flash poste uma notificação PnP (consulte GUID_LAMP_RESOURCES_AVAILABLE em Notificações Assíncronas) indicando que o hardware subjacente está agora disponível. Ao receber essa notificação, um aplicativo de lanterna tem permissão para programar flash adequadamente.

  • Se um aplicativo de lanterna for iniciado primeiro, uma sessão de captura pode sequestrar o hardware do flash sem consentimento explícito.

    • Ao "seqüestrar", queremos dizer que um IHV/OEM pode implementar um protocolo arbitrário (possivelmente por meio da interface GUID_DEVINTERFACE_CAMERA_FLASH), de modo que o minidriver AVStream tenha permissão para adquirir flash como se o hardware não estivesse sendo usado.

    • Quando ocorre uma interceptação, o driver flash deve postar outra notificação PnP (consulte GUID_LAMP_RESOURCES_LOST em Notificações Assíncronas) indicando que o flash foi reatribuído involuntariamente para que o aplicativo de lanterna possa tomar as ações necessárias (atualizando a interface do usuário, por exemplo).

Compartilhando o Flash entre vários aplicativos de lanterna

Se a câmera não estiver envolvida e dois aplicativos de lanterna forem executados em sequência, o driver deverá continuar atendendo ao primeiro cliente que já adquiriu a interface GUID_DEVINTERFACE_LAMP e rejeitar todos os clientes adicionais até que o primeiro libere a interface eventualmente.

Em outras palavras, a interface GUID_DEVINTERFACE_LAMP permite apenas um cliente de lanterna por vez e o primeiro cliente que adquire a interface impede que outros clientes sejam executados (câmera/AVStream excluída).

GUID da classe de interface do dispositivo

Um driver flash IHV/OEM capaz de dar suporte à lanterna independente do MediaCapture deve registrar-se no GUID da Classe de Interface do Dispositivo , GUID_DEVINTERFACE_LAMP.

Atributo Configurações
Identificador GUID_DEVINTERFACE_LAMP
Classe GUID {6C11E9E3-8232-4F0A-AD19-AAEC26CA5E98}

O GUID da classe de interface do dispositivo GUID_DEVINTERFACE_CAMERA_FLASH pode ser definido de forma personalizada por IHVs/OEMs. No entanto, o GUID da classe de interface do dispositivo de GUID_DEVINTERFACE_LAMP é definido pelo Windows.

Por contrato, um driver que expõe a interface do dispositivo, GUID_DEVINTERFACE_LAMP, é necessário para dar suporte às seguintes funções (consulte seções posteriores para obter detalhes):

  • IOCTL_LAMP_GET_CAPABILITIES_{WHITE|COLOR} – obtém todos os modos (por exemplo, somente branco versus cor) com suporte pelo hardware subjacente

  • IOCTL_LAMP_{GET|SET}_MODE – obtém ou define o modo atual

  • IOCTL_LAMP_{GET|SET}_INTENSITY_{WHITE|COLOR} – obtém ou define a intensidade da luz

  • IOCTL_LAMP_{GET|SET}_EMITTING_LIGHT – obtém ou define o estado flash (por exemplo, ON/OFF)

Se um dispositivo tiver mais de um hardware flash de tipos diferentes (por exemplo, um LED branco e um flash Xenon) e esses hardwares forem controlados por drivers flash diferentes, cada driver deverá expor o mesmo GUID_DEVINTERFACE_LAMP interface com uma ID de instância exclusiva.

Propriedade de Interface do Dispositivo

Como um dispositivo de computação pode ter zero ou mais dispositivos flash em painéis diferentes, a API da Lâmpada do WinRT precisa de um mecanismo para enumerar todo o hardware flash de modo que um aplicativo possa programar uma instância específica.

Para dar suporte à enumeração do dispositivo, semelhante ao driver da câmera, o driver flash deve associar uma estrutura ACPI _PLD v2 a cada interface GUID_DEVINTERFACE_LAMP como dados de propriedade da interface.

IOCTL_LAMP_GET_CAPABILITIES_WHITE

A solicitação de E/S IOCTL_LAMP_GET_CAPABILITIES_WHITE consulta as capacidades do flash quando o dispositivo está configurado para emitir luz branca.

Definição

#define IOCTL_LAMP_BASE FILE_DEVICE_UNKNOWN
#define IOCTL_LAMP_GET_CAPABILITIES_WHITE \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0000, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para um buffer do tipo LAMP_CAPABILITIES_WHITE. Consulte Comentários para obter detalhes.

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp>AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp-AssociatedIrp.SystemBuffer> é preenchido com todos os recursos compatíveis com o hardware flash.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado. Ele definirá Irp-IoStatus.Information> com o número de bytes necessários para manter o buffer.

Observações

Por requisito, um flash cujo driver dá suporte à interface GUID_DEVINTERFACE_LAMP é necessário para dar suporte à emissão de luz branca. A carga deste IOCTL é definida da seguinte maneira:

// The output parameter type of IOCTL_LAMP_GET_CAPABILITIES_WHITE.
typedef struct LAMP_CAPABILITIES_WHITE
{
    BOOLEAN IsLightIntensityAdjustable;
} LAMP_CAPABILITIES_WHITE;

O campo IsLightIntensityAdjustable indica se o nível de luminância pode ser programado. Se esse campo for avaliado como false, isso significa que o dispositivo subjacente só dá suporte ao botão de ativação/desativação e a intensidade da luz não pode ser ajustada.

IOCTL_LAMP_GET_CAPABILITIES_COLOR

A solicitação de E/S IOCTL_LAMP_GET_CAPABILITIES_COLOR consulta os recursos do flash quando o dispositivo está configurado para emitir luz de cor.

Definição

#define IOCTL_LAMP_GET_CAPABILITIES_COLOR \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0001, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp->AssociatedIrp.SystemBuffer aponta para um buffer do tipo LAMP_CAPABILITIES_COLOR. Consulte Comentários para obter detalhes.

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp->AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp-AssociatedIrp.SystemBuffer> é preenchido com todos os recursos compatíveis com o hardware flash.

Bloco de Status de E/S

O driver define Irp->IoStatus.Status como STATUS_SUCCESS ou o status de erro apropriado. Ele definirá Irp-IoStatus.Information> com o número de bytes necessários para manter o buffer.

Observações

O conteúdo deste IOCTL é definido da seguinte forma:

// The output parameter type of IOCTL_LAMP_GET_CAPABILITIES_COLOR.
typedef struct LAMP_CAPABILITIES_COLOR
{
    BOOLEAN IsSupported;
    BOOLEAN IsLightIntensityAdjustable;
} LAMP_CAPABILITIES_COLOR;

O primeiro campo, IsSupported, indica se o flash pode emitir luz de cor. Se o hardware não der suporte à luz de cor, o driver deverá definir esse campo como false.

O segundo campo, IsLightIntensityAdjustable, indica se o nível de luminância pode ser programado. Se o flash não suportar luz colorida (por exemplo, se IsSupported retornar falso), o cliente deve descartar o valor de IsLightIntensityAdjustable.

IOCTL_LAMP_GET_MODE

"A solicitação de E/S 'IOCTL_LAMP_GET_MODE' consulta o modo com o qual o flash está configurado no momento."

Definição

#define IOCTL_LAMP_GET_MODE \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para um buffer do tipo LAMP_MODE, que é definido da seguinte maneira:

typedef enum LAMP_MODE
{
    LAMP_MODE_WHITE = 0,
    LAMP_MODE_COLOR
} LAMP_MODE;

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp->AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp->AssociatedIrp.SystemBuffer é preenchido com um valor LAMP_MODE.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado. Ele definirá Irp->IoStatus.Information com o número de bytes necessários para armazenar um valor DWORD.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

IOCTL_LAMP_SET_MODE

A solicitação de E/S IOCTL_LAMP_SET_MODE define o modo no qual o flash opera.

Definição

#define IOCTL_LAMP_SET_MODE \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0003, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para um buffer do tipo LAMP_MODE.

Parâmetros de saída

Nenhum.

Bloco de Status de E/S

O driver define Irp->IoStatus.Status como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

IOCTL_LAMP_GET_INTENSITY_WHITE

A solicitação de E/S IOCTL_LAMP_GET_INTENSITY_WHITE consulta a intensidade da luz quando o flash é configurado para emitir luz branca.

Definição

#define IOCTL_LAMP_GET_INTENSITY_WHITE \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0004, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para uma estrutura de LAMP_INTENSITY_WHITE. Consulte Comentários para obter detalhes.

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp->AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp-AssociatedIrp.SystemBuffer> é preenchido com as informações de intensidade da luz.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

Observações

O tipo de carga útil deste IOCTL é definido da seguinte forma:

// The I/O parameter type of IOCTL_LAMP_{GET|SET}_INTENSITY_WHITE.
typedef struct LAMP_INTENSITY_WHITE
{
    BYTE Value;
} LAMP_INTENSITY_WHITE;

O campo Valor é a intensidade da luz branca em porcentagem entre 0 e 100, inclusive.

IOCTL_LAMP_SET_INTENSITY_WHITE

A solicitação de E/S de IOCTL_LAMP_SET_INTENSITY_WHITE define o flash como a intensidade de luz especificada.

Definição

#define IOCTL_LAMP_SET_INTENSITY_WHITE \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0005, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para uma estrutura de LAMP_INTENSITY_WHITE (consulte IOCTL_LAMP_GET_INTENSITY_WHITE para obter detalhes).

Parâmetros de saída

Nenhum.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

IOCTL_LAMP_GET_INTENSITY_COLOR

A solicitação de E/S de IOCTL_LAMP_GET_INTENSITY_COLOR consulta a intensidade da luz quando o flash é configurado para emitir luz de cor.

Definição

#define IOCTL_LAMP_GET_INTENSITY_COLOR \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0006, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp->AssociatedIrp.SystemBuffer aponta para uma estrutura de LAMP_INTENSITY_COLOR. Consulte Comentários para obter detalhes.

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp->AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp-AssociatedIrp.SystemBuffer> é preenchido com as informações de intensidade da luz.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

Observações

O tipo de conteúdo deste IOCTL é definido da seguinte maneira:

// The I/O parameter type of IOCTL_LAMP_{GET|SET}_INTENSITY_COLOR.
typedef struct LAMP_INTENSITY_COLOR
{
    BYTE Red; // Red light intensity in percentage (0-100)
    BYTE Green; // Green light intensity in percentage (0-100)
    BYTE Blue; // Blue light intensity in percentage (0-100)
} LAMP_INTENSITY_COLOR;

IOCTL_LAMP_SET_INTENSITY_COLOR

A solicitação de E/S IOCTL_LAMP_SET_INTENSITY_COLOR ajusta o flash à intensidade de luz especificada.

Definição

#define IOCTL_LAMP_SET_INTENSITY_COLOR \
    CTL_CODE(IOCTL_LAMP_BASE, 0x0007, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para uma estrutura de LAMP_INTENSITY_COLOR (consulte IOCTL_LAMP_GET_INTENSITY_COLOR para obter detalhes).

Parâmetros de saída

Nenhum.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

IOCTL_LAMP_GET_EMITTING_LIGHT

O pedido de E/S IOCTL_LAMP_GET_EMITTING_LIGHT verifica se a luz (flash) está ligada.

Definição

#define IOCTL_LAMP_GET_EMITTING_LIGHT
    CTL_CODE(IOCTL_LAMP_BASE, 0x0008, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para um buffer do tipo BOOLEAN.

IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength é o comprimento do buffer (em bytes) passado no campo Irp->AssociatedIrp.SystemBuffer.

Parâmetros de saída

Irp-AssociatedIrp.SystemBuffer> é preenchido com o estado do flash, sendo que TRUE indica que o flash está ativado (por exemplo, emitindo luz); FALSE, caso contrário.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado. Ele definirá Irp->IoStatus.Information com o número de bytes necessários para armazenar um valor DWORD.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

IOCTL_LAMP_SET_EMITTING_LIGHT

A solicitação de E/S IOCTL_LAMP_SET_EMITTING_LIGHT ativa/desativa a luz (flash).

Definição

#define IOCTL_LAMP_SET_EMITTING_LIGHT
    CTL_CODE(IOCTL_LAMP_BASE, 0x0009, METHOD_BUFFERED, FILE_ANY_ACCESS)

Parâmetros de entrada

Irp-AssociatedIrp.SystemBuffer> aponta para um buffer do tipo BOOLEAN, com VERDADEIRO indicando LIGADO; FALSO indicando DESLIGADO.

Parâmetros de saída

Nenhum.

Bloco de Status de E/S

O driver define Irp-IoStatus.Status> como STATUS_SUCCESS ou o status de erro apropriado.

Se uma sessão do MediaCapture estiver transmitindo dados no momento em que essa solicitação é feita, o driver deverá retornar um erro (STATUS_RESOURCE_IN_USE) por meio de Irp-IoStatus.Status>.

Notificações assíncronas

Conforme descrito em Casos de Uso de Simultaneidade, o driver flash deve enviar notificações PnP para relatar a disponibilidade dos recursos. Isso pode ser feito chamando IoReportTargetDeviceChange (ou IoReportTargetDeviceChangeAsynchronous) com os seguintes GUIDs dependendo do cenário:

  • O recurso flash foi removido porque uma sessão de captura (ou outro aplicativo de lanterna) é iniciada:

    Atributo Configurações
    Identificador GUID_LAMP_RESOURCES_LOST
    Classe GUID {F770E98C-4403-48C9-B1D2-4EEC3302E41F}
  • O recurso flash agora está disponível:

    Atributo Configurações
    Identificador GUID_LAMP_RESOURCES_AVAILABLE
    Classe GUID {185FE7CE-2616-481B-9094-20BB893ACD81}