libvideo on GitHub

Введение

В современном мире человечество окружает огромное количество различного цифрового контента, основной частью этого контента является видео.

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

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

В статье будет приведено описание написанной кроссплатформенной (Windows/Android) библиотеки кодирования и декодирования видео с возможностью масштабировать, кадрировать кадры.

Стек

  • языки программирования: C++ 17, Java11.
  • системы сборки: CMake, Gradle.
  • пакетный менеджер: Conan.
  • библиотека unit-тестирования: Google C++ Testing Framework (gtest).

Предметная область

Как было описано выше видео с исходным разрешением невозможно передавать по сети из-за большого веса передаваемых данных. Поэтому на стороне отправителя видео специальным образом подготавливается с помощью специальных алгоритмов перед отправкой, т.е. кодируется. На стороне пользователя для того чтобы воспроизвести видео оно декодируется. За кодирование/декодирование отвечает кодек (co/dec) - специальное аппаратное устройство или программа.

Кодек H.264

Внутри библиотека построена c использованием кодека H.264 реализованным с помощью libx264.

Кодек H.264 является очень известным, поэтому не будем останавливаться на его описании, лишь уточним, что используется именно он, потому что его использование (в т.ч. libx264) является бесплатным и потому что H.264 один из самых распространненых кодеков.

Описание работы

Windows

На Windows реализовано:

  • Создание программного кодера, аппаратного кодера, программного декодера и аппаратного декодера
  • Вывод кодированных данных в заданный пользователем callback, вывод декодированного кадра в заданный пользователем callback, вывод декодированного кадра на Windows окно
  • Фильтры масштабирования и кадрирования кадра
  • Логирование (encoded size, resolution, framerate и т.д.) в консоль и на Windows окно при программном декодировании

Общий алгоритм работы с библиотекой:

1) Создание кодера и декодера. На этом этапе возможно воспользоваться встроенным методом для поиска существующих на системе кодеров и декодеров, если в системе нет аппаратных кодеров или декодеров, будут использоваться программные.
2) Добавление callback-а кодеру или декодеру для вывода данных.
3) Добавление Windows окон декодеру для вывода кадров.
4) Добавление фильтров масштабирования и кадрирования к кодеру и декодеру.
5) Включение/выключение логирования.
6) Кодирование и декодирование.

Описанный выше алгоритм является общим и не все его части необходимы для работы. Например, добавление фильтров необязательно, создавать кодер и декодер в "одном месте" необязательно и т.д.

Для создания кодера необходимо задать параметры width, height, bit_rate, framerate и H.264 preset. Для создания декодера необходимо задать параметры width и height.

Android

На Android реализовано:

  • Создание программного кодера, программного декодера и аппаратного декодера
  • Вывод кодированных данных в Java byte array
  • Вывод декодированного кадра на Android Surface при аппаратном декодировании
  • Логирование (encoded size, resolution, framerate и т.д.) в Android Logcat

Общий алгоритм работы с библиотекой:

1) Создание кодера и декодера. На этом этапе возможно создать аппаратный декодер, в него нужно передать ссылку на Android Surface.
2) Включение/выключение логирования.
3) Кодирование и декодирование.

Для создания кодера необходимо задать параметры width, height, bit_rate, framerate и H.264 preset. Для создания декодера необходимо задать параметры width, height и extradata. Параметр extradata является опциональным, по сути представляет собой SPS и PPS данные, которые необходимые для запуска аппаратного декодера, но если пользователь не задал extradata, декодер попытается получить эти данные из входящего потока от кодера.

Тестирование

Windows

Для Windows написано тестовое приложение, которое реализует работу со всеми основными функциями библиотеки.

При запуске тестового приложения с программным кодированием и декодированием с разрешением 1280x720 и фильтром масштабирования на 0.5x выводное Windows окно выглядит так, как представлено на рис. 1.

Рис. 1 - Декодированный кадр 1280x720 с фильтром масштабирования 0.5x

При этом в консоли будет следующий вывод, представленный на рис. 2.

Рис. 2 - Логированная информация о кодированном и декодированном кадре

При использовании аппаратного кодирования и декодирования производительность повышается. Например, кодирование с помощью AMD AMF сжимало размер SMPTE кадра с разрешением 320x240 и изначальным размером 307200 байт до размера 17 байт при повторной отправке того же кадра. Программный кодер libx264 в таких условиях сжимал кодированные данные кадра до 750 байт.

Android

Для Android написано два тестовых приложения использующих камеру телефона, как входной поток для кодирования. В первом используется программное кодирование и декодирование, во втором программное кодирование и аппаратное декодирование.

На рис. 3 представлена работа приложения с программным декодированием. На нем отображается сверху поток с камеры, снизу декодированное изображение.

Рис. 3 - Android тестовое приложение с программным кодированием декодированием

Второе приложение имеет одно окно, созданное как Android Surface, на которое выводит аппаратно декодированный кадр. На рис. 4 представлен результат работы тестового приложения.

Рис. 4 – Android тестовое приложение с аппаратным декодированием

Unit-тесты

Для unit-тестирования используется gtest.

Создано 9 unit-тестов проверяющие корректность работы кодирования, декодирования и фильтров.

На рис. 5 представлено сообщение, выведенное gtest о успешном завершении всех тестов.

Рис. 5 - Успешное завершение всех тестов

Вывод

В статье описана разработанная библиотека под Windows и Android, позволяющая кодировать, декодировать, масштабировать, кадрировать кадры.

Для библиотеки созданы тестовые приложения под Windows и Android. Созданы 9 unit-тестов.

Для удобной сборки библиотеки написан скрипт, подробнее в README библиотеки на GitHub.

Лицензия

Файл LICENSE на GitHub

Используемые библиотеки