Considerações sobre a implementação do roteamento de fluxo

No Windows 7, APIs de plataforma de alto nível que usam APIs de áudio principais, como APIs Media Foundation, DirectSound e Wave, implementam o recurso de roteamento de fluxo manipulando a comutação de fluxo de um dispositivo existente para um novo ponto de extremidade de áudio padrão. Os aplicativos de mídia que usam essas APIs usam o comportamento de roteamento de fluxo sem modificações na origem. Os clientes WASAPI diretos podem usar as notificações enviadas pelos componentes Core Audio e implementar o recurso de roteamento de fluxo.

Os clientes WASAPI diretos (aplicativos de mídia que usam o WASAPI diretamente) recebem notificações de novos dispositivos e sessões de áudio enviadas pelos componentes Core Audio. O comportamento do recurso de roteamento de fluxo é definido pela forma como o aplicativo manipula essas notificações.

A API MMDevice e a sessão de áudio enviam notificações sobre alterações de estado do dispositivo e alterações de sessão para clientes WASAPI na forma de retornos de chamada. Para obter essas notificações, o cliente deve registrar sua implementação de IMMNotificationClient e IAudioSessionEvents. Para obter mais informações, consulte Notificações relevantes para roteamento de fluxo.

No cenário de fone de ouvido USB descrito em Roteamento de fluxo, um aplicativo está reproduzindo um fluxo de áudio e usa MMDeviceAPI e WASAPI para renderizar o fluxo no dispositivo de renderização padrão, Speaker. Quando o dispositivo padrão é alterado, o aplicativo recebe uma notificação IMMNotificationClient . O aplicativo também recebe notificações IAudioSessionEvents indicando que o usuário removeu o dispositivo de ponto de extremidade de áudio ou que o formato de fluxo foi alterado para o dispositivo ao qual a sessão de áudio está conectada. Ao receber as notificações, o aplicativo interrompe a transmissão para o ponto de extremidade do alto-falante e reabre o fluxo para renderização no ponto de extremidade padrão atual, o fone de ouvido.

diagram of data flow for device notifications.

Em resposta a essas notificações, o cliente pode reabrir o fluxo no novo dispositivo padrão no novo formato selecionado pelo usuário.

Gestão de Córregos

A lista a seguir resume as etapas que um cliente WASAPI deve executar para fornecer a funcionalidade de comutação de fluxo.

  1. Aguarde a notificação IMMNotificationClient relevante. Se o dispositivo for o dispositivo padrão, a notificação IMMNotificationClient::OnDefaultDeviceChanged será recebida.

  2. Se um novo dispositivo estiver disponível, obtenha uma referência ao ponto de extremidade do novo dispositivo. Chame IMMDeviceEnumerator::GetDefaultAudioEndpoint para o novo dispositivo padrão. Se o novo dispositivo não for o dispositivo padrão, você poderá recuperá-lo chamando IMMDeviceEnumerator::GetDevice. Para obter mais informações, consulte Obtendo o ponto de extremidade do dispositivo para roteamento de fluxo.

  3. Aguarde o valor IAudioSessionEvents::OnSessionDisconnected com o motivo.

    Observação

    Como todas essas operações são assicronas, a ordem em que o aplicativo recebe notificações de alteração de dispositivo e desconexão de sessão não pode ser prevista. O aplicativo deve implementar o tratamento de notificações para receber essas notificações em qualquer ordem. No entanto, normalmente, o aplicativo recebe o valor AudioSessionDisconnect antes da notificação de alteração de dispositivo padrão.

     

  4. Avalie o valor do motivo e determine se o fluxo precisa ser transferido para outro ponto de extremidade de áudio ou se o fluxo precisa ser reinicializado com um novo formato.

  5. Pare o streaming para o dispositivo padrão antigo se o motivo indicar que o fluxo deve ser redirecionado para o novo dispositivo padrão.

  6. Realizar cálculos de mapeamento de posição.

  7. Abra o fluxo no novo dispositivo e transfira todas as informações de estado.

  8. Retome o streaming no novo dispositivo padrão.

  9. Manipule a saída do dispositivo padrão antigo.

Para que a operação de comutação de fluxo pareça perfeita, ela deve ser feita o mais rápido possível. Isso depende do desempenho dos componentes envolvidos na reinicialização do fluxo no novo dispositivo.

Considerações sobre mapeamento de posição

Quando o aplicativo obtém notificações IMMNotificationClient e IAudioSessionEvents , ele pode rotear os fluxos existentes para o novo dispositivo padrão. Quando um fluxo de áudio existente é interrompido e aberto no novo dispositivo, a renderização no novo dispositivo deve começar na posição em que o fluxo foi interrompido no dispositivo antigo. Para fazer isso, o aplicativo deve ter a última posição de dispositivo conhecida, para calcular a posição inicial no novo dispositivo. Por exemplo, essa posição pode ser usada como o deslocamento delta para mapeamento de posição subsequente. Quando o fluxo começa a ser renderizado, a nova posição do dispositivo pode ser remapeada para a posição do dispositivo armazenado em cache.

As etapas a seguir resumem o processo de fazer uma transição de fluxo contínua.

  1. Armazene em cache a última posição do dispositivo do fluxo no dispositivo antigo.
  2. Pare o fluxo no dispositivo antigo.
  3. Execute cálculos de remapeamento para obter a nova posição.
  4. Comece a renderizar o fluxo no novo dispositivo.
  5. Solte o fluxo antigo.

Durante a transição, o aplicativo deve garantir que o relógio não fique fora de sincronização, resultando em fluxos de áudio e vídeo fora de sincronia. Isso pode ocorrer se as amostras de vídeo continuarem a ser renderizadas enquanto o fluxo de áudio é roteado para o novo dispositivo. O aplicativo deve armazenar em cache a posição do relógio para o cálculo de remapeamento e garantir que as amostras de vídeo não sejam renderizadas até que o fluxo de áudio seja reaberto no novo dispositivo, para que, quando o clipe retomar a renderização, os fluxos de áudio e vídeo sejam sincronizados. Em alguns casos, onde o tempo de apresentação para renderizar os quadros de vídeo é baseado no relógio de áudio, é suficiente parar o fluxo de áudio até que a comutação de fluxo seja concluída e nenhuma outra implementação de mapeamento de posição para o fluxo de vídeo seja necessária para a sincronização de áudio e vídeo.

Se durante a renderização, IAudioRenderClient::GetBuffer retornar um erro porque o dispositivo antigo foi perdido, o aplicativo não precisará parar o fluxo antigo porque a operação de streaming já foi encerrada. Para obter informações sobre como lidar com esse erro, consulte Recuperando-se de um erro de dispositivo inválido.

Sobre a API MMDevice

Sobre o WASAPI

Roteamento de fluxo