Статья описывает способ авто-тестирования аппаратно-программных комплексов видеоконференц связи. Позволяет решить проблему быстрой оценки снижения качества видео после передачи через проблемные каналы IP сети.
Предисловие
Интернет протокол IP, как протокол сетевого уровня, весьма неудобное место для организации видеоконференций.
Видео-конференсинг близок по своим требованиям к коммуникациям в реальном времени с гарантированной доставкой информации. Если не будет обеспечена быстрота передачи информации от отправителя к получателю, то пользоваться видео-конференсингом станет неудобно или даже невозможно. Если не обеспечивается целостность информации, то организовать конференцию в такой сети будет технологически/алгоритмически сложно.
Так-же конференсинг использует видео-кодеки, которые сжимают кадры таким образом, что фреймы зависят друг от друга. И при потери одного фрейма на декодере будет искажение, которое распространится на следующие кадры.
Какие протоколы IP обычно используют.
Транспортный протокол TCP/IP, ориентирован на соединение, обеспечивает целостность и упорядоченность информации, но на перегруженных проблемных каналах он может вносить большие задержки.
Транспортный протокол UDP/IP фактически является надстройкой над IP, добавляя к нему аресацию по портам. Поэтому он наследует все свойства IP протокола.
Главное положительное свойство UDP — быстрота передачи пакетов.
Поэтому в большинстве случаев используется протокол UDP, чтобы обеспечить коммуникацию в реальном времени. Но если нет возможности использовать UDP, устанавливается TCP соединение.
Заранее не известно какой протокол будет использоваться. Поэтому стеки отправки и получения видео-потоков на отправителе и получателе должны быть готовы к любым свойствам из совокупных свойств интернет каналов.
Какие положительные свойства предоставляет интернет для конференсига?
Главное положительное свойство — это то, что интернет в принципе есть и он распрастранён по всей планете.
Все остальные свойства отрицательные:
не гарантирует доставку пакетов, не гарантирует последовательность и равномерность прихода пакетов, не гарантирует целостность пакетов.
Так же интернет не обеспечивает постоянными пропускную способность каналов и задержку передачи пакетов от отправитель к получателю
Для того, чтобы преодолеть отрицательные свойства интернет каналов стеки используют специальные протоколы с обратной связью и различные технологии.
Например для видео потоков:
RTP/RTCP, JiterBuffer, NACK, FEC, перезапросы для восстановления картинки в кадрах, ведение статистики по каналу и обмен ею между отправителем и получателем, и т.п.
Но главная технология — это адаптация качества передаваемого видеопотока к свойствам канала.
Что нас не устраивает в существующих метриках оценок падения качества видео и что мы предлагаем
Есть метрики сравнивающие исходную картинку и результирующую — PSNR, SSIM, и т.п. Но у нас видео — это вектора этих картинок во времени.
Метрики видео, например VMAF, используют машинное обучение. Какие критерии оценок в них заложены? Что для них важнее для снижения оценки качества, что нет? Например, учитывает ли они пропуски кадров или задержки во времени или повторяющиеся кадры?
Мы же хотим создать простое устройство уровня счётчиков искажений в потоке.
Для этого мы однозначно классифицировали все искажения, которые могут быть в результирующем видео относительно референса и научились надёжно подсчитывать количество каждого из этих искажений во время автотестирования.
У каждого такого подсчитанного искажения есть весовой коэффициент, который обуславливает, как этот тип искажения снижает результирующую оценку.
Путем несложных вычислений, мы получаем единую оценку падения качества видео.
При этом мы можем посмотреть более детальную информацию — оценки по каждому из типов искажений, или посмотреть какие типы искажений были зафиксированы и количество каждого из них.
Мы можем изменять весовые коэффициенты искажений для разных типов авто-тестов, вплоть до игнорирования каких-либо искажений.
Перечисление вносимых в видео-поток искажений
Перечисляем искажения от мало-значимых к более негативным для результатов автотестов.
1. Снижение качества кадров (картинок) в видео.
Появляется большая грануляция или эффект размытия, нечеткости. Возникает, когда мы сжимаем битрейт энкодером и соответственно снижаем качество видео. При ещё большем снижении битрейта мы перед кодированием уменьшаем размер(разрешение) кодируемого видео.
2. Уменьшение количества кадров в секунду.
Снижение битрейта кодированного потока за счет уменьшения количества кадров в секунду. Это умеют делать даже сами видео-кодеки, когда кодек видит, что не влезает в указанный ему битрейт, он может начать не кодировать(игнорировать, отбрасывать, фильтровать) часть фреймов.
3. Зрительный эффект длительной остановки воспроизведения.
Кадры идут (среднее значение FPS не падает), но на кадрах одно и то-же изображение. Этот эффект возникает, если в цепочке обработки видеокадров есть модуль, который по таймеру выбирает последний кадр из входного потока, формируя новую последовательность временных меток. Если входной поток будет приходить неравномерно пачками с запозданиями (проблемы с сетью или высокая загрузка ЦП), то этот модуль может несколько раз проиграть один и тот-же кадр.
4. Пропуски цепочек кадров.
Как следствие — длительные остановки воспроизведения, при которых значение количества кадров в секунду падает относительно средней величины. Эффект обычно возникает при потерях, когда был запрос опорной информации для восстановления развалившейся картинки, и до прихода кадра, который восстановит картинку, был включен режим неотображения развалившегося видео.
5. Рассыпание картинки в кадре.
Алгоритмы адаптации и восстановления потерянной в сети информации не сработали, декодер декодирует видео поток с неполными фреймами, с пропусками фреймов и с выключенным режимом невоспроизведения видео до прихода опорного кадра. Но даже если режим невоспроизведения видео до прихода опорного кадра был включен, мы всё-равно можем получить рассыпание картинки по ряду других причин.
( Приоритетность типов искажений может быть другая, предложенный порядок не обязателен. )
Фактор времени
Наш отдел разрабатывает одну из частей общего большого проекта. Эта часть ответственна за работу с аудио-видео потоками на сервере и клиентах, написана на C++. Это самые низкоуровневые интерфейсы и их соответствующие модули реализаций в нашем общем проекте.
Для себя мы решили, что авто-тестирование, на уровне задач нашего отдела, должно быть быстрым. Разработчик может набросать часть кода по своей текущей задаче и кинуть этот промежуточный код на авто-тестирование. Полное авто-тестирование ветки кода задачи разработчика не должно длиться более 1 часа. За это время разработчик, локально у себя в проекте, может продолжить накидывать следующую часть кода, ну или сходить на обед.
Уже через час у него будет ответ системы авто-тестирования, внес ли он, предыдущей порцией кода, какие-либо ухудшения или проблемы.
Нам это удобно.
Есть более высокоуровневые модули нашего общего проекта. Там тоже есть свои системы авто-тестирования. В аспекте авто-тестов мы дополняем и возможно перепроверяем друг-друга.
Нумерация кадров видео, метод номерных меток
Для того, чтобы соотносить кадры из референсного с кадрами из результирующего видео, почти очевидно, что нужно их пронумеровать, проиндексировать.
В других статьях, коллегами по предметной области, было предложено называть такое видео калиброванным.
Что мы использовали для калибровки видео ранее
В первых наших версиях мы нумеровали кадры обычным текстом с числами арабских цифр, а на принимающей стороне распознавали номер кадра. Сейчас есть много ПО для распознавания текста на изображении.

Если текст в указанном месте не обнаруживался, мы предполагали, что это кадр с рассыпанной картинкой, т.е. с самым негативным фактором для результатов автотестов.
Потом мы определились с отрицательными моментами в таком способе.
Распознавание текста в кадрах занимало много времени, даже на порядок большее, чем записать эту строку в изображение. См. «Фактор времени».
А поскольку калиброванное видео для авто-тестов у нас лежит подготовленным заранее, нам важнее именно быстрое распознавание номера картинки в результирующем видео, чтобы за короткое время провести автотестирование.Если мы не можем прочитать текст номера — предполагаем, что картинка рассыпалась. Но всего один экземпляр текста с номером может быть в другом месте изображения, нежели где произошло рассыпание. Писать один большой текст на всё изображение — значит сделать видео более синтетическим, что делает работу видеокодека не идентичной, нежели если бы он кодировал реальное видео с камеры. Написать несколько строк с номерами в разных местах картинки — распознавание картинки станет ещё более длительным.
Номерные метки — как мы калибруем исходное видео сейчас
Мы решили использовать небольшие квадратики на изображении и в их компоненты цветовой модели закодировать номер кадра. Размер квадратиков может быть любым, но скорее коррелирует с размером калибруемого видео, например для FHD мы взяли 60x60.
В большинстве случаев, и мы тоже, используем YUV формат сырого видео для обработки и кодирования видео-кодеком.
Используем UV две компоненты для укладки туда номера кадра.
Могли бы использовать все три YUV компоненты, но яркостную Y компоненту не задействуем, чтобы видео оставалось более реалистичным, не синтетическим.
Предполагаем, что нам нужно исходное видео длительностью 1 минута и с частотой кадров 30 в секунду — всего 3600 кадров.
Каждая из этих двух UV компонент — цветоразностные компоненты — каждый пиксель в них — это октет, который имеет диапазон 0...255.
256 в степени 2 = 65536. Кажется всё, одного квадратика хватит. Но нет.
Видеокодирование — это тема сжатия с потерей качества. Качество теряется не только в аспекте чёткости изображения, но и в аспекте цветности.
Цвет в результирующем видео будет искаженным, но при этом значение цвета останется где-то рядом.
Разобьём компоненту на N диапазонов, N в степени 2 и будет то число, которое мы сможем закодировать в одном квадратике.
После проб, мы разбили 0...255 диапазон на 4 равных отрезка.
( Но значение 4, кратность этого значения 2м, и то что отрезки равные — это совершенно не обязательно, значения могут быть разными, достаточными для ваших целей. Мы просто остановились на тех простых значениях коэффициентов, которые у нас заработали с большим запасом. Например, если разбить на 6 или 8 — тоже работает. )
4 в степени 2 = 16, не хватает для 3600. Цикличность номера кадра нам не нужна. Тогда пусть будут 3 таких квадратика в виде полоски этих квадратиков.
4 в степени (2 умножить на 3) = 4096, для нашего 1 минутного теста этого достаточно.
При подготовке калиброванного видео, в квадратики цветовых компонент закладываются центральные значения отрезков, соответствующих кодируемым числам, которые являются составляющими номера кадра видео.
В нашем случае:
число 0 — отрезок 0...63 — значение закладываемое при калибровке 32,
число 1 — отрезок 64...127 — значение закладываемое при калибровке 96,
число 2 — отрезок 128...191 — значение закладываемое при калибровке 160,
число 3 — отрезок 192...255 — значение закладываемое при калибровке 224.

— пример калиброванного видео.
Как быстро считать номер кадра из номерной метки
Считать номер кадра из нашей номерной метки на картинке — это быстро.
Для этого достаточна небольшая группа операций обратная кодированию числа в метку: — определение диапазона отрезка числа 0...3, умножения, сложения, деления.
Распознавание рассыпания картинки
Почему нам важен факт такого контроля рассыпания картинок во время автотестов.
PSNR конечно сильно снизит качество при сравнении исходной и рассыпанной результирующей картинок. Но снижение качества на PSNR — это не обязательно рассыпание картинки, нету однозначного критерия, чтобы понять через метрику PSNR, что картинка рассыпалась. И при этом PSNR метрика у нас самая малозначимая.
Получение номера картинки из номерной метки — быстрая операция. Это значит, что мы можем расположить на картинке много таких меток.
В наших примерах мы сделали их 6 штук, 4-ре ближе к углам и 2-ве ближе к середине.
Предполагаем, что этого будет достаточным, чтобы любое рассыпание затронуло хотя-бы одну из меток. Можно расположить на картинке ещё больше номерных меток, хотя желательно, чтобы большая часть картинки была оригинальной.
Рассыпание картинки на номерной метке однозначно исказит значения UV компонент и это сделает неправильным восстановленное из метки значение номера кадра. Но для определения рассыпания картинки нам это и нужно.
Примеры рассыпанного видео, где видно, что номерные метки стали разными, потому-что часть меток тоже искажены.


Алгоритм распознавания рассыпания картинки прост — читаем номер кадра из всех меток, он должен совпадать на всех, значит это и есть номер кадра видео.
Если значение номера кадра не совпадает хотя-бы на одной из меток — значит картинка с рассыпанием.
( Конечно здесь могут быть разные варианты, например, игнорировать одну ошибку в одной временной метке, если в ней ошибочна только одна из 6ти UV компонент. )
Как результат, при использовании нескольких номерных меток мы однозначно распознаем номер кадра или с высокой степенью вероятности узнаем, что картинка рассыпалась.
Автотестирование и его результаты
Рассыпание картинок, вместе с длительными остановками воспроизведения видео значительно снижают общее впечатление использования систем видеоконференцсвязи. Поэтому, применяя наш способ подсчёта результирующей оценки падения качества видео, мы максимально снижаем оценку именно на этих видах искажений.
В большинстве типов наших тестов, рассыпание картинки приводит к отрицательному результату прохождения автотестов.
Метод номерных меток, для темы этой статьи, даёт нам возможность нумеровать кадры видео и распознавать рассыпание картинки.
Но мы авто тестируем и звук и звук+видео, информация о нумерации кадров используется и там (будет в следующей статье).
Наша метрика оценки падения качества видео представляет из себя простой набор счетчиков искажений в результирующем видео. Это абсолютно объективная оценка. Мы можем судить о результатах авто-тестов по простым количественным величинам.
Но если мы хотим получить единую оценку падения качества видео, как уже субъективно представляем, то корректируем единую оценку приоритетами весовых коэффициентов каждого типа искажений.
Резюмируя
Две основные идеи/новшества затронуты в этой статье.
Анализ и перечисление возможных искажений в результирующем видео. Калькуляция простых счётчиков каждого из искажений. Формирование нужной для нас единой оценки из этих счётчиков.
Номерные метки — как способ калибровки(нумерации) кадров исходного видео для надёжной калькуляции счётчиков искажений.
Примеры исследования работоспособности номерных меток
Достоверность и быстрота распознавания заложенного в картинку числа — это важно в целом для реализации наших простых счётчиков искажений в видео.
Попробуем, на примере FHD, при каком низком битрейте наш метод калибровки начнёт давать сбои при распознавании номера кадра.
240 Кбит/сек. — для FHD — это минимальный или уже неиспользуемый битрейт, потому-что при декодировании мы получаем видео весьма плохого качества.
— пример такого 240 Кбит/сек FHD видео.
Но наш способ калибровки пока ‘держит удар’, работает даже на таком 240 Кбит/сек. FHD видео.
Пробуем 120 Кбит/сек. — для FHD — это уже скорее неадекватный битрейт.
— пример такого 120 Кбит/сек FHD видео.
Наш способ калибровки перестал работать. Он даёт периодические сбои, потому-что искажения в видео, в т.ч. цветоразностных компонент, настолько большие, что достоверное восстановление закодированного номера кадра становится невозможным.
Но стеки кодирующие видео и отправляющие его в сеть не будут так делать. Если они кодируют и отправляют в сеть видеопоток всё с меньшим битрейтом, они предварительно уменьшают размер кодируемого видео.
Этим они добиваются разумного соотношения размера видео и битрейта.
Так и сделаем.
Уменьшаем размер видео FHD 1920x1080 → 352x198. При этом мы сразу теряем качество картинки в разы, но предполагаем, что этот размер будет адекватным для кодирования на 120 Kbps.
Уменьшаем видео до 352x198, кодируем на 120 Kbps, декодируем и скалируем/увеличиваем размер видео обратно до исходного FHD.
И теперь наш способ калибровки на 120 Kbps работает. Нет ни одной ошибки.
— пример такого транскодирования.
Пожалуй, стеки кодирования и отправки видео в сеть делают правильно.