Design para latência reduzida

A versão Android 4.1 introduziu alterações internas na estrutura 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 projeto inicial, que continuou a evoluir ao longo do tempo. Ter uma boa compreensão desse design deve ajudar os fornecedores de OEM e SoC de dispositivos 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 faixas

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++ revisa a solicitação AUDIO_OUTPUT_FLAG_FAST e pode, opcionalmente, negar a solicitação no nível do cliente. Se decidir passar a solicitação, ele o faz 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 revisa 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 ou não aceita, via bit CBLK_FAST do bloco de controle de memória compartilhada.

Os fatores que afetam a decisão incluem:

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

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

Roscas do misturador

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

Misturador rápido

Características

A rosca do misturador rápido fornece esses recursos:

  • Mixagem do submix 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 efeitos de mixagem

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 superior de cinco ms, se necessário para estabilidade de agendamento. Esse número foi escolhido para que, contabilizando o pipeline completo do buffer, 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 mixer 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 forneça dados.

Bloqueio

Idealmente, o encadeamento rápido do mixer 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.

Relação com outros componentes

O mixer rápido tem pouca interação direta com os clientes. Em particular, ele não vê as operações no nível do binder, 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 faixa, 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 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 sua submixagem.

Relação com outros componentes

O mixer normal interage amplamente com o mundo externo, incluindo threads de binder, gerenciador de política de áudio, thread de mixer rápido e faixas de cliente.

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

Bandeiras

O bit AUDIO_OUTPUT_FLAG_FAST é uma dica. Não há garantia de que o pedido será atendido.

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

TRACK_FAST é um conceito de cliente -> servidor.