Потоковое аудио: получение RTP-потока с помощью Gstreamer - Задержка

В настоящее время я играю с проектом AudioOverIP и задаюсь вопросом, не могли бы вы мне помочь. У меня есть локальная сеть с источником звука (Dante/AES67-RTP-Stream), который я хотел бы распространить на несколько приемников (SBC (например, RaspberryPi) с аудиовыходом (например, разъем для наушников):

PC-->Audio-USB-Dongle-->AES67/RTP-Multicast-Stream-->LAN-Network-Switch-->RPI (Gstreamer --> AudioJack)

В настоящее время я использую Gstreamer для конвейера:

gst-launch-1.0 -v udpsrc uri=udp://239.69.xxx.xx:5004 caps="application/x-rtp,channels=(int)2,format=(string)S16LE,media=(string)audio,payload=(int)96,clock-rate=(int)48000,encoding-name=(string)L24" ! rtpL24depay ! audioconvert ! alsasink device=hw:0,0

Все работает нормально, но если я смотрю видео на ПК и слушаю аудио из RPI, у меня возникает некоторая задержка (~200-300 мс), поэтому мои вопросы:

  1. Пропускаю ли я что-то в моем конвейере Gstreamer, чтобы уменьшить задержку?
  2. Какова минимальная задержка, ожидаемая при использовании RTP-потоков, <50 мс?
  3. Будет ли задержка возникать из-за сети или из-за скорости RPi?
  4. Поскольку мой аудиовход не является входом Gstreamer, я предполагаю rtpjitterbuffer или подобное не помогло бы уменьшить задержку?

1 ответ

TL;DR: Проверьте размерupdsrcбуфер, если вы настаиваете на использовании gstreamer. Вместо этого я рекомендую использовать реализацию Равенны.

В вопросе большое внимание уделяется gstreamer, который может не понадобиться для достижения вашей цели. Этот ответ больше касается звука через IP (AoIP ) в ARM Linux в целом, а также вопросов 2 и 3.

Во-первых, вы упоминаете Видео и Аудио в своих настройках. Если все сделано профессионально, для этого потребуется решение AV over IP, которое обеспечивает синхронизацию звука и видео. Примерами являются DanteAV или что-то совместимое с SMPTE 2110. Мне кажется, ваш подход подходит для хобби-проектов. Имейте в виду, что Dante в режиме AES67 имеет некоторые ограничения .

2. AoIP с низкой задержкой:

Да, вполне возможно получить задержку Dante/AES67/RTP ниже 50 мс, если ваше устройство имеет сопоставимые характеристики с NXP i.MX8 . Для справки: задержка туда и обратно в 4–5 мс легко достигается с помощью Dante и профессионального оборудования.

Если ваша цель: «Передача потока AES67 с малой задержкой в ​​RPi», я предлагаю взглянуть на реализацию Ravenna для Linux. Равенна похожа на Данте, но более совместима с AES67. Равенна и AES67 используют RTP точно так же.

Существует две основные реализации Linux с открытым исходным кодом:

  1. Merging Technologies предоставляет « оригинал » только с коммерческой поддержкой. Инструмент управления является проприетарным и предназначен только для x86.
  2. Существует форк , содержащий полезные патчи и программное обеспечение для управления с открытым исходным кодом.
  • В обоих случаях вам все равно придется перекрестно скомпилировать код для ARM/RPi.
  • Лично я рекомендую использовать вилку.

Dante предоставляет производителям реализацию Linux, но вы, вероятно, не получите ее: https://www.audinate.com/products/manufacturer-products/dante-embedded-platform.

3. Источники задержки

Для AoIP существуют разные источники задержки:

  • Время упаковки: время учета образцов в пакете, ок. 1 мс.
  • Сеть: зависит от вашего оборудования и настроек, ок. От < 1 мс до многих секунд.
  • Буфер приемника: настраиваемый, ок. < 1 мс до многих мс.
  • Обработка и ЦАП на ресивере.

Время пакета должно составлять 1 мс, поскольку Dante использует обязательный профиль AES67 (48 кГц, 48 выборок/пакет). Я предполагаю, что ваш отправитель обработал это правильно, но я не могу сказать.

В сети вам следует использовать как минимум гигабитные коммутаторы и кабели Cat 5e. Обязательно следуйте рекомендациям по переключателям и настройке (особенно отключите EEE). Если часы отправителя и получателя синхронизированы, запустите tcpdump или Wireshark на обоих, чтобы получить точную оценку задержки в сети. Фильтровать полезную нагрузку проще всего по порту, например RTP:port 5004 or port 9875Данте:portrange 14336-14591. Включение/выключение звука легко заметить на снимке (latency = T_send - T_recv).

Если все в порядке, посмотрите на буфер приема или обработку на получателе. Звук с низкой задержкой RPi кажется возможным . Тем не менее, вы можете измерить скорость АЦП/ЦАП на RPi, а также оптимизировать свой Linux (от безголового режима до исправления ядра в реальном времени до создания оптимизированного дистрибутива с помощью Yocto в крайнем случае.

1., 4. Гстример

Как уже было сказано, если вы можете это сделать, используйте реализацию Ravenna Linux. Вся его цель — эффективно получать потоки AES67. И все же, некоторые идеи по поводу вашего конвейера:

Документы говорят _udpsrcдобавляет настраиваемый буфер размером ок. от 50 КБ до макс. 100 КБ. Пакет RTP AES67 с временем пакета 1 мс и частотой дискретизации 48 кГц имеет 342 байта. Таким образом, буфер эквивалентен50 kB / 342 Byte * 1ms = 146ms

-> Это вероятный виновник.

Я думаю, тебе не нуженrtpjitterbuffer. В его документах говорится о «ретрансляции». AES67 не выполняет повторную передачу полезных данных (AFAIK). Кроме того, в конвейер добавляется еще один буфер на 200 пакетов, то есть 200 мс при времени пакета 1 мс. Заказ и т. д. по-прежнему должны работать, поскольку AES67 использует стандартные временные метки RTP. Но это будет стоить вам задержки и, вероятно, не понадобится в локальной сети. Кажется, rtpjitterbuffer больше ориентирован на RTP глобальной сети, чем AES67 локальной сети.

Также нашел эту статью , в которой используется тот же конвейер, что и у вас.

Если это не решит вашу проблему, выясните, где именно возникает задержка. Также расскажите нам, как измерялась задержка.

Другие вопросы по тегам