Дизайн для уменьшения задержки

В выпуске Android 4.1 были внесены изменения внутренней структуры для более низкой задержки вывода звука. Были внесены минимальные изменения в общедоступный клиентский API или HAL API. В этом документе описывается первоначальный проект, который со временем продолжал развиваться. Хорошее понимание этого дизайна должно помочь OEM-производителям устройств и поставщикам SoC правильно реализовать дизайн на своих конкретных устройствах и наборах микросхем. Эта статья не предназначена для разработчиков приложений.

Создание трека

Клиент может дополнительно установить бит AUDIO_OUTPUT_FLAG_FAST в параметре audio_output_flags_t конструктора AudioTrack C++ или AudioTrack::set() . В настоящее время единственными клиентами, которые делают это, являются:

Реализация AudioTrack C++ проверяет запрос AUDIO_OUTPUT_FLAG_FAST и может при необходимости отклонить запрос на уровне клиента. Если он решает передать запрос, он делает это, используя бит TRACK_FAST параметра track_flags_t фабричного метода IAudioTrack IAudioFlinger::createTrack() .

Аудиосервер AudioFlinger просматривает запрос TRACK_FAST и может дополнительно отклонить запрос на уровне сервера. Он информирует клиента о том, был ли запрос принят, через бит CBLK_FAST блока управления общей памятью.

К факторам, влияющим на решение, относятся:

  • Наличие потока быстрого микшера для этого выхода (см. ниже)
  • Отслеживание частоты дискретизации
  • Наличие клиентского потока для выполнения обработчиков обратного вызова для этой дорожки
  • Размер буфера отслеживания
  • Доступные слоты быстрого доступа (см. ниже)

Если запрос клиента был принят, это называется «ускоренный путь». В противном случае это называется "обычный трек".

Смесительные потоки

Когда AudioFlinger создает обычный поток микшера, он решает, создавать ли также быстрый поток микшера. И обычный микшер, и быстрый микшер связаны не с конкретной дорожкой, а скорее с набором дорожек. Всегда есть нормальная резьба смесителя. Поток быстрого микшера, если он существует, подчиняется обычному потоку микшера и действует под его контролем.

Быстрый миксер

Функции

Поток быстрого микшера предоставляет следующие возможности:

  • Микширование субмикса обычного микшера и до 7 клиентских быстрых дорожек
  • Затухание на дорожке

Пропущенные функции:

  • Преобразование частоты дискретизации для каждой дорожки
  • Эффекты для каждой дорожки
  • Эффекты микса

Период

Быстрый микшер запускается периодически с рекомендуемым периодом от двух до трех миллисекунд (мс) или немного большим периодом в пять мс, если это необходимо для стабильности расписания. Это число было выбрано таким образом, чтобы с учетом всего буферного конвейера общая задержка составляла порядка 10 мс. Возможны меньшие значения, но это может привести к увеличению энергопотребления и вероятности сбоев в зависимости от предсказуемости планирования ЦП. Возможны и большие значения, вплоть до 20 мс, но это приводит к ухудшению общей задержки, поэтому их следует избегать.

Планирование

Быстрый микшер работает с повышенным приоритетом SCHED_FIFO . Ему требуется очень мало процессорного времени, но он должен выполняться часто и с низким дрожанием планирования. Джиттер выражает изменение времени цикла: это разница между фактическим временем цикла и ожидаемым временем цикла. Запуск слишком поздно приведет к сбоям из-за опустошения. Слишком ранний запуск приведет к сбоям из-за извлечения из ускоренной дорожки до того, как дорожка предоставит данные.

Блокировка

В идеале поток быстрого микшера никогда не блокируется, кроме HAL write() . Другие случаи блокировки в быстром микшере считаются ошибками. В частности, избегаются мьютексы. Вместо этого используются неблокирующие алгоритмы (также известные как алгоритмы без блокировки). Дополнительную информацию по этой теме см. в разделе Избегание инверсии приоритетов .

Связь с другими компонентами

Быстрый миксер мало взаимодействует с клиентами напрямую. В частности, он не видит операций на уровне компоновщика, но имеет доступ к блоку управления общей памятью клиента.

Быстрый микшер получает команды от обычного микшера через очередь состояний.

Помимо извлечения данных дорожки, взаимодействие с клиентами осуществляется через обычный микшер.

Основным приемником быстрого микшера является аудио HAL.

Обычный микшер

Функции

Все функции включены:

  • До 32 дорожек
  • Затухание на дорожке
  • Преобразование частоты дискретизации для каждой дорожки
  • Обработка эффектов

Период

Период вычисляется как первое целое кратное периода быстрого смесителя, который составляет >= 20 мс.

Планирование

Обычный микшер работает с повышенным приоритетом SCHED_OTHER .

Блокировка

Обычному микшеру разрешено блокировать, и он часто делает это в различных мьютексах, а также в блокирующем канале для записи своего субмикса.

Связь с другими компонентами

Обычный микшер интенсивно взаимодействует с внешним миром, включая потоки связывания, диспетчер политики аудио, поток быстрого микшера и клиентские дорожки.

Приемник обычного микшера — это блокирующая труба, ведущая к дорожке 0 быстрого микшера.

Флаги

AUDIO_OUTPUT_FLAG_FAST — это подсказка. Нет никакой гарантии, что запрос будет выполнен.

AUDIO_OUTPUT_FLAG_FAST — это концепция уровня клиента. Он не появляется на сервере.

TRACK_FAST — это концепция клиент -> сервер.