Design para latência reduzida

O lançamento do Android 4.1 introduziu mudanças internas na estrutura para um caminho de saída de áudio de latência mais baixa . Houve alterações mínimas na API do cliente público ou na API HAL. Este documento descreve o projeto inicial, que continuou a evoluir ao longo do tempo. Ter um bom entendimento desse design deve ajudar os fornecedores OEM e SoC do dispositivo a implementar o design corretamente em seus dispositivos e chipsets específicos. Este artigo não se destina a desenvolvedores de aplicativos.

Criação de faixa

O cliente pode, opcionalmente, definir o bit AUDIO_OUTPUT_FLAG_FAST no parâmetro audio_output_flags_t do construtor AudioTrack C++ ou AudioTrack::set() . Atualmente, os únicos clientes que o fazem são:

A implementação do AudioTrack C++ analisa a solicitação AUDIO_OUTPUT_FLAG_FAST e pode, opcionalmente, negar a solicitação no nível do cliente. Se ele decidir passar a solicitação, ele o fará usando o bit TRACK_FAST do parâmetro track_flags_t do método de fábrica IAudioTrack IAudioFlinger::createTrack() .

O servidor de áudio AudioFlinger analisa a solicitação TRACK_FAST e pode, opcionalmente, negar a solicitação no nível do servidor. Informa ao cliente se a requisição foi aceita ou não, via bit CBLK_FAST do bloco de controle de memória compartilhada.

Os fatores que impactam a decisão incluem:

  • Presença de um thread de misturador rápido para esta saída (veja abaixo)
  • Taxa de amostragem da faixa
  • Presença de um segmento de cliente para executar manipuladores de retorno de chamada para esta faixa
  • Tamanho do buffer de rastreamento
  • Slots de fast track disponíveis (veja abaixo)

Se a solicitação do cliente foi aceita, isso é chamado de "faixa rápida". Caso contrário, é chamado de "pista normal".

Fios do misturador

No momento em que o AudioFlinger cria um thread de mixer normal, ele decide se também cria ou não um thread de mixer rápido. Tanto o mixer normal quanto o mixer rápido não estão associados a uma trilha específica, mas sim a um conjunto de trilhas. Há sempre um fio misturador normal. O encadeamento do misturador rápido, se existir, é subserviente ao encadeamento do misturador normal e age sob seu controle.

Misturador rápido

Características

O encadeamento do misturador rápido fornece estes recursos:

  • Mixagem do sub-mix do mixer normal e até 7 faixas rápidas do cliente
  • Atenuação por faixa

Recursos omitidos:

  • Conversão de taxa de amostragem por faixa
  • Efeitos por faixa
  • Por mix de efeitos

Período

O misturador rápido é executado periodicamente, com um período recomendado de dois a três milissegundos (ms), ou um período ligeiramente maior de cinco ms, se necessário para a estabilidade do agendamento. Esse número foi escolhido para que, considerando o pipeline de buffer completo, a latência total seja da ordem de 10 ms. Valores menores são possíveis, mas podem resultar em maior consumo de energia e chance de falhas, dependendo da previsibilidade do agendamento da CPU. Valores maiores são possíveis, até 20 ms, mas resultam em latência total degradada e, portanto, devem ser evitados.

Agendamento

O misturador rápido é executado com prioridade SCHED_FIFO elevada. Ele precisa de muito pouco tempo de CPU, mas deve ser executado com frequência e com baixo jitter de agendamento. Jitter expressa a variação no tempo de ciclo: é a diferença entre o tempo de ciclo real versus o tempo de ciclo esperado. Correr muito tarde resultará em falhas devido ao underrun. Correr muito cedo resultará em falhas devido à retirada de uma pista rápida antes que a pista tenha fornecido dados.

Bloqueio

Idealmente, o encadeamento do mixer rápido nunca é bloqueado, exceto em HAL write() . Outras ocorrências de bloqueio dentro do mixer rápido são consideradas bugs. Em particular, mutexes são evitados. Em vez disso, algoritmos sem bloqueio (também conhecidos como algoritmos sem bloqueio) são usados. Consulte Evitando a inversão de prioridade para saber mais sobre este tópico.

Relação com outros componentes

O misturador rápido tem pouca interação direta com os clientes. Em particular, ele não vê operações no nível do fichário, mas acessa o bloco de controle de memória compartilhada do cliente.

O mixer rápido recebe comandos do mixer normal por meio de uma fila de estado.

Além de puxar os dados da trilha, a interação com os clientes é feita por meio do mixer normal.

O coletor primário do mixer rápido é o áudio HAL.

misturador normal

Características

Todos os recursos estão ativados:

  • Até 32 faixas
  • Atenuação por faixa
  • Conversão de taxa de amostragem por faixa
  • Processamento de efeitos

Período

O período é calculado para ser o primeiro múltiplo integral do período do misturador rápido que é >= 20 ms.

Agendamento

O mixer normal é executado com prioridade SCHED_OTHER elevada.

Bloqueio

O mixer normal tem permissão para bloquear, e geralmente o faz em vários mutexes, bem como em um canal de bloqueio para gravar seu submix.

Relação com outros componentes

O mixer normal interage extensivamente com o mundo externo, incluindo encadeamentos de ligação, gerenciador de política de áudio, encadeamento de mixer rápido e faixas de cliente.

A pia do mixer normal é um tubo de bloqueio para a trilha 0 do mixer rápido.

Bandeiras

O bit AUDIO_OUTPUT_FLAG_FAST é uma dica. Não há garantia de que a solicitação será atendida.

AUDIO_OUTPUT_FLAG_FAST é um conceito de nível de cliente. Não aparece no servidor.

TRACK_FAST é um conceito de cliente -> servidor.