VoIP Contest: Round 2
Задача этапа
Реализовать систему для качественных аудиозвонков между двумя пользователями с заданным интерфейсом, опираясь на данные системы для тестирования.
К участию приглашаются все желающие. Вы можете прислать свою работу даже если не принимали участия в первом этапе.
Входные данные
- Библиотека libtgvoip. В конкурсе будет использоваться исходный код по состоянию на коммит f775311.
- Публичный интерфейс звонков между двумя пользователями в заголовочном файле TgVoip.h. Через этот интерфейс библиотека подключена в тестирующем консольном клиенте tgvoipcall, он же в ближайшем времени будет использован и в мобильных клиентах.
- Набор утилит и звуковых файлов для тестирования и оценки качества звонков.
- Telegram API не требуется.
Задание
- Улучшить реализацию звонков одним из возможных путей.
- Сохранить публичный интерфейс звонков TgVoip.h.
Условия
- Использовать только C++ (за исключением скриптов сборки и тестирования), с прицелом на code portability. Будет плюсом, если библиотека собирается под Android.
- Допускается изменять протокол обмена данными, а также использовать альтернативный/самописный протокол. При этом необходимо не терять E2E-шифрование (открытые голосовые данные не должны уходить ни на какой сервер, их ключ шифрования должен быть наследован от encryption_key, передаваемого в библиотеку). Сохранение совместимости с текущей реализацией будет плюсом.
- Допускается игнорирование параметра адреса и тега Relay-сервера Telegram, использование своего/стороннего промежуточного Relay-сервера (STUN, TURN, xirsys, etc). При отправке работы рекомендуется использовать хостинг в Амстердаме или центральной Европе, чтобы при тестировании минимизировать задержку у жюри.
- Допустимо использовать сторонний код только с GPL-совместимыми лицензиями.
- За рамками конкурса остаются P2P (
TgVoipEndpointType::Inet
,TgVoipEndpointType::Lan
), TCP Relay (TgVoipEndpointType::TcpRelay
), SOCKS proxy (TgVoipProxy
), Data saving mode (TgVoipDataSaving
), Traffic stats (TgVoipTrafficStats
), а также функцииsetGlobalServerConfig
,onSignalBarsUpdated
,setMuteMicrophone
, флагTGVOIP_USE_CUSTOM_CRYPTO
. Они не будут использоваться/учитываться при тестировании, их можно игнорировать. - Обязательно необходимо поддержать
TgVoipState
,onStateUpdated
,TgVoipAudioDataCallbacks
. - Необходимо уделить особое внимание потокобезопасности кода, стараться избегать дедлоков.
Примечания
- P2P должен быть принудительно выключен на стороне библиотеки.
- IPv6 не будет поддерживаться сервером во время тестирования.
- Рекомендуется использовать UDP протокол.
- Работы будут тестироваться на серверах с Debian GNU/Linux 10.1 (buster), x86-64. Обязательно проверьте корректность работы библиотеки на чистой системе перед отправкой работы.
- Тестирование звонков будет производиться только между двумя клиентами, использующими одну и ту же конкурсную работу. Совместимость с текущей реализацией не является обязательной, но положительно повлияет на оценку жюри.
- Клиенты одного звонка могут быть запущены на разных физических серверах.
На выходе требуется ZIP-файл (максимальный размер - 200MB) со следующей структурой:
submission.zip -> libtgvoip.so - подключаемая библиотека -> README - инструкция по сборке, описание проделанной работы -> src - директория с исходным кодом -> deb-packages.txt - текстовый файл с названиями пакетов внешних зависимостей для сборки, разделенных переводом строки
Возможные подходы
Ниже перечислены возможные подходы при участии в конкурсе, по возрастанию степени их радикальности. Каждый из них имеет свои плюсы и будет иметь шансы на приз и победу при должном объёме и качестве проделанной работы.
- Находить и исправлять конкретные проблемы в текущей реализации библиотеки. Например, исправлять потенциальные deadlock'и или находить сетевые условия, в которых качество голоса/задержка хуже, чем могло бы быть. Для всех подобных проблем необходимо подробно описать условия для воспроизведения и предпринятые меры.
- Переписать библиотеку, сохранив совместимость с текущими клиентами (оставив сетевые протоколы без изменения).
- Использовать сторонние библиотеки/протоколы, теряя совместимость. Опционально использовать свой Relay-сервер.
Критерии оценки
- Соблюдение всех условий
- Объем кода, количество внешних зависимостей
Все работы будут протестированы с одинаковыми наборами входных данных (аудиосемпл + сетевые условия). Выходные файлы будут оценены с помощью tgvoiprate, полученная метрика будет учитываться, но не будет являться основной при оценке работ.
Test Suite
Для тестирования в процессе разработки предоставляется набор утилит и звуковые файлы. Скачать на GitHub ».
Набор утилит позволяет:
- Совершать псевдо-звонок с использованием бинарного so-файла с библиотекой. Вместо реального входного сигнала с микрофона используются звуковые семплы с речью, либо тишиной для каждой из сторон. Выходной сигнал у получателя записывается в аналогичный звуковой файл.
- Программно задавать условия сети для одного из участников: потери пакетов, повышенная latency, пропускная способность канала, а также программно изменять их в процессе звонка.
- Получать числовую оценку качества полученного на выходе звукового файла у получателя по сравнению со входным файлом и preprocessed файлом (который реально уходит по сети) у отправителя.
- Записывать имена входных и выходных файлов, а также рейтинги в CSV файл, для дальнейшего анализа.
- Управлять всем вышеперечисленным с помощью PHP-скрипта.
- Агрегировать рейтинги по версиям библиотеки.
Ниже приведена инструкция для Debian GNU/Linux 10.1 (buster), x86-64.
Подготовка системы
1. Необходимо установить deb-пакеты:
$ sudo apt-get install php
2. Для эмулирования разных сетевых условий используется netem, а также ip-netns для наложения сетевых ограничений только на один из процессов (у отправителя). Перед началом работы необходимо однократно запустить скрипт
$ sudo bash ./tests/setup-netns.sh
$ sudo tc qdisc list
Он настроит network namespace client1
с виртуальным интерфейсом v-peer1
для дальнейшей работы утилиты звонков, больше при нормальной работе вызывать его не потребуется. Если какая-то из команд выведет ошибки, которые не пропадают при повторном её запуске, то возможно на вашей системе необходимо установить/включить netem или ip-netns.
3. Поскольку мы будем часто менять параметры netem для изменения сетевых условий, и это требует root/sudo, необходимо отключить интерактивный запрос пароля при вызове таких команд. Для этого запустим:
$ whoami
user
$ sudo visudo
В самый конец файла добавляем строку
user ALL=(ALL) NOPASSWD: /usr/bin/ip netns exec client1 *
заменив user
на вывод команды whoami
. Сохраняем файл (в случае редактора Vim, необходимо нажать Esc, затем набрать :wq
, нажать Enter).
4. После этого необходимо указать свой token для работы с VoIP Contest API. Для этого необходимо заменить значение по умолчанию 111222333444:AAABBBCCCDDD
в файле tests/token.php на то значение, которое Вы получили от @jobs_bot во время регистрации на этот этап конкурса (или в рассылке).
Обратите внимание, что если Вы участвовали в первом этапе конкурса VoIP, Вам необходимо получить у бота новый токен для второго этапа.
Call + Rate
Основной файл с описанием сценария тестирования - tests/call.php. В нём задается список so-файлов библиотек для тестирования, количество итераций звонков, а также наборы сетевых условий. Для примера файл заполнен демонстрационным содержимым, рекомендуется изменить его под свои нужды.
Запуск с помощью:
$ php tests/call.php
Будет выполнен весь описанный сценарий тестирования. Это может занять длительное время, каждая итерация займёт порядка 10-20 секунд в зависимости от длительности выбранного аудиосемпла. В папках preprocessed и out появятся файлы с аудиоданными, отправляемыми по сети и полученные получателем, соответственно. Каждый звонок также будет сразу оценен, а результаты оценки записаны в CSV-файл. Если доступ к серверу осуществляется через SSH, рекомендуется использовать nohup/screen для длительных запусков, чтобы вызов не прерывался потерей соединения.
В конце выполнения скрипт также выведет средние значения оценок для каждой из протестированных версий, например:
Version stable (3234 ratings)
=============================================
ScoreCombined: mean 3.063, stddev: 0.924
ScorePreprocess: mean 4.257, stddev: 0.408
ScoreOutput: mean 3.39, stddev: 0.942
....
Здесь ScorePreprocess характеризует, насколько деградирует качество звука в preprocessed файле по сравнению с входным. 1.0-5.0, где 1.0 - полностью испортилось, 5.0 - осталось неизменным.
Величина ScoreOutput характеризует, насколько деградирует качество звука у получателя по сравнению с preprocessed у отправителя. 1.0-5.0, где 1.0 - полностью испортилось, 5.0 - осталось неизменным.
Величина ScoreCombined характеризует, насколько деградирует качество звука у получателя по сравнению с исходным аудио отправителя, то есть некоторая аггрегация ScorePreprocess и ScoreOutput. 1.0-5.0, где 1.0 - полностью испортилось, 5.0 - осталось неизменным.
Эту статистику всегда можно получить позднее из CSV-файла, запустив
$ php tests/mean.php
Очистить все накопленные preprocessed, out файлы и CSV файл можно с помощью:
$ sh tests/clean.sh
Предполагаемое использование
Один из вариантов организации процесса разработки библиотеки может быть следующим:
- Вести разработку библиотеки в отдельной директории. На время разработки писать подробные логи внутри библиотеки в stdout/stderr.
- После каждого значимого изменения, выполнять сборку, совершать
git commit
, копировать выходной .so файл библиотеки в директориюlib
Test Suite с уникальным именем, например libtgvoip.COMMIT.so и добавлять в список тестируемых библиотек libraries в tests/call.php. - Запускать в фоне тестирование изменений, продолжать вести разработку (поскольку процесс тестирования длительный).
- Изучать выходные логи своей библиотеки (пишутся в .log файлы в папке out), а также прослушивать аудиофайлы, если это требуется, для примеров с наиболее низкими рейтингами.
- Находить и исправлять проблемы. Возращаться к п. 2.
Когда качество достигнет допустимого уровня, можно сфокусироваться на поиске новых сетевых условий, в которых результат работы библиотеки значительно портится, например перепады в скорости соединения, процентах потерь и исправлять там, где это возможно.