Design para latência reduzida

A versão Android 4.1 introduziu alterações na estrutura interna para um caminho de saída de áudio de menor latência . Houve alterações mínimas na API do cliente público ou na API HAL. Este documento descreve o design inicial, que continuou a evoluir ao longo do tempo. Ter um bom entendimento desse design deve ajudar os fornecedores de dispositivos OEM e SoC 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 trilhas

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 fazem isso são:

A implementação AudioTrack C++ analisa a solicitação AUDIO_OUTPUT_FLAG_FAST e pode opcionalmente negar a solicitação no nível do cliente. Se decidir repassar 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 solicitação foi aceita ou não, através do bit CBLK_FAST do bloco de controle de memória compartilhada.

Os fatores que impactam a decisão incluem:

  • Presença de um thread mixer rápido para esta saída (veja abaixo)
  • Rastrear taxa de amostragem
  • Presença de um thread de cliente para executar manipuladores de retorno de chamada para esta faixa
  • Rastrear o tamanho do buffer
  • Slots de fast track disponíveis (veja abaixo)

Se a solicitação do cliente for aceita, isso é chamado de “via rápida”. Caso contrário, é chamada de “faixa normal”.

Tópicos misturadores

No momento em que o AudioFlinger cria um thread de mixer normal, ele decide se deseja ou não criar 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. Sempre há um thread de mixer normal. O thread do mixer rápido, se existir, é subserviente ao thread do mixer normal e atua sob seu controle.

Misturador rápido

Características

O thread do mixer rápido oferece estes recursos:

  • Mixagem do sub-mix do mixer normal e até 7 fasttracks do cliente
  • Atenuação por trilha

Recursos omitidos:

  • Conversão de taxa de amostragem por faixa
  • Efeitos por faixa
  • Efeitos por mixagem

Período

O mixer rápido funciona periodicamente, com um período recomendado de dois a três milissegundos (ms), ou um período ligeiramente superior de cinco ms, se necessário para estabilidade do agendamento. Este número foi escolhido para que, contabilizando o buffer pipeline completo, a latência total seja da ordem de 10 ms. Valores menores são possíveis, mas podem resultar em aumento do 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 mixer rápido funciona 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 tarde demais resultará em falhas devido à insuficiência. Correr muito cedo resultará em falhas devido à saída de uma pista rápida antes que a pista forneça dados.

Bloqueio

Idealmente, o thread do mixer rápido nunca bloqueia, exceto em HAL write() . Outras ocorrências de bloqueio no mixer rápido são consideradas bugs. Em particular, os mutexes são evitados. Em vez disso, são usados ​​algoritmos sem bloqueio (também conhecidos como algoritmos sem bloqueio). Consulte Evitando a inversão de prioridade para obter mais informações sobre este tópico.

Relacionamento com outros componentes

O mixer 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 através de uma fila de estados.

Além de extrair dados da trilha, a interação com os clientes é feita através do mixer normal.

O coletor principal do mixer rápido é o HAL de áudio.

Misturador normal

Características

Todos os recursos estão habilitados:

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

Período

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

Agendamento

O mixer normal funciona com prioridade SCHED_OTHER elevada.

Bloqueio

O mixer normal tem permissão para bloquear, e muitas vezes faz isso em vários mutexes, bem como em um tubo de bloqueio para escrever sua submixagem.

Relacionamento com outros componentes

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

O dissipador 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 cliente -> servidor.