NACK (Negative Acknowledgments) - механизм запроса потерянных пакетов. NACK вместо уведомления отправителя о полученном, уведомляет его о том, что было потеряно. Отправитель знает только о пакетах, которые необходимо отправить повторно.
- NACK работает посредством запросов RTCP (Generic NACK);
- Поддержка NACK в ВКСТ включается скрытым параметром в конфигурационном файле phone.conf, расположенном в /home/protei/Protei-MFAT-V/config <SupportRTCP_NACK value="true" /> (по умолчанию включен);
- Поддержка NACK в ВКСС включается параметром SupportRTCP_NACK_General = <bool> в конфигурационном файле mcu.cfg, расположенный в /home/protei/config/Protei-VCS/MCU.Router/config. NACK по умолчанию включен (аналогично явно заданному значению параметра SupportRTCP_NACK_General = 1;);
- Основная информация о работе NACK в течение вызова доступна в статистике ВКСТ в графическом и WEB-интерфейсе:
а также в ВКСС интерфейсе администратора (VCS GUI):
Приведённая статистика отражает работу механизма с точки зрения обработки NACK запросов от удалённой стороны и посылки пакетов повторно. То есть наличие каких-то запросов в статистике свидетельствует о потерях на отправку (приеме на удаленной стороне). Количество отправленных NACK в статистике не фиксируется.
Значения счётчика “Кол-во неуспешных NACK запросов” больше нуля означает, что удалённая сторона запрашивала повторную отправку пакетов, но ВКСС/ВКСТ не смогла это сделать, как правило по причине завершения таймаута хранения RTP пакетов.
Таймаут хранения RTP пакетов составляет от 500мс до 2с (при отправке низкого fps).
“Кол-во неуспешных NACK запросов за вызов” отображает статистику за период активного вызова.
- NACK должен поддерживаться и согласоваться на обеих сторонах обмена медиа трафика. NACK в SIP/SDP:
... a=rtcp-fb:* ccm fir a=rtcp-fb:* nack a=rtcp-fb:* nack pli ...
, где a=rtcp-fb:* nack - поддержка NACK.
- В случае аудио NACK не работает: разовые единичные потери для аудио не столь критичны. Round-trip time запроса NACK и потенциально успешный ответ удаленной стороны, как правило, приведет к задержке обработки аудио и его выдаче в звуковую подсистему ОС (разъезжание с видео, выпадение слов/фраз, артефакты);
- Прежде чем запрашивать удаленную сторону отправить потерянный пакет, ВКСС/ВКСТ вычисляет целесообразность данной процедуры: если время отправки NACK запроса и ответа удаленной стороны (rtt) больше, чем очередь RTP перед потерянным пакетом, то запрос отправляться не будет;
- NACK может работать одновременно с FEC;
- NACK запросы на удалённую сторону могут не приводить к желаемому результату. Например, всё тот же таймаут хранения пакетов на удалённой стороне или потеря самих NACK пакетов;
Плюсы NACK:
- Не перегружает полосу пропускания избыточным трафиком (не влияет на основной битрейт);
- Эффективен в случае небольших единичных потерь.
Минусы NACK:
- При большом rtt/ping могут появиться “залипы” в видео (во время ожидания потерянного пакета весь остальной трафик в очереди не обрабатывается)
- При большом пинге может не работать, т.к. размеры очереди на приёме может не хватить на ожидание (rtt) NACK запроса/заново отправленного пакета, а также у удалённой стороны запрошенный пакет может уже не храниться в момент получения NACK запроса;
- Неэффективен в случае постоянных множественных потерь.
Для нормализации входящего трафика (восстановление порядка пакетов, восстановление пропусков через NACK) используется RTP-очередь, размер которой задается параметром “Максимальный размер очереди на приеме RTP c видео, мс” (аналогичный параметр для аудио).
- Параметр “Максимальный размер очереди на приёме RTP c видео в случае поддержки NACK и заморозки изображения при потерях, мс” работает только в совокупности с включенным “Режим “замораживания” картинки” (и, разумеется, согласованном NACK).
Параметр переопределяет “обычный” (описанный выше) размер очереди при соблюдении этих условий;
Аналогичные параметры в ВКСС находятся в конфигурационном файле mcu.cfg, расположенный в /home/protei/config/Protei-VCS/MCU.Router/config.
Поддержка NACK в ВКСС включается параметром SupportRTCP_NACK_General = <bool> в конфигурационном файле mcu.cfg, расположенный в /home/protei/config/Protei-VCS/MCU.Router/config.:
AudioRtpRxQueueDepth = <int>; #O,D=-1(не задано, будет использоваться 100), максимальный размер очереди аудио rtp на вход VideoRtpRxQueueDepth = <int>; #O,D=-1(не задано, будет использоваться 100), максимальный размер очереди видео rtp на вход VideoRtpRxQueueDepthWhenNackAndFreezeEnabled = <int>; #O,D=500, максимальный размер очереди видео rtp при согласованном RTCP NACK и режиме заморзки изображения при потерях
- RTP очередь поможет нивелировать джиттер или большой rtt/ping (в разумных пределах - до 100 мс) в случае наличия потерь. Очередь нет смысла задавать очень большой (максимум 500 мс, это для ping’а примерно в 200 мс);
- При наличии потерь очередь будет вносить задержку (фиксируется потери => ожидание восстановления через FEC / запрос NACK => ожидание восстановления). При наличии потерь и большого размера очереди следует ожидать “залипания” видео.
Рекомендации:
- для видео нужно подобрать размер RTP очереди такой, чтобы размер RTP очереди ~= (максимальный rtt/ping на СПД) x1.5;
- для аудио - рекомендации указаны в статье: «Джиттер-буфер для устройств вывода звука»