Материал статьи взят с моего дзен-канала.


Введение


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


Mediastreamer2 это VoIP-движок, лежащий в основе популярного open-source проекта программного voip-телефона Linphone. В Linphone Mediastreamer2 реализует все функции связанные со звуком и видео. Подробный список возможностей движка можно увидеть на этой странице Mediastreamer. Исходный код находится здесь: GitLab.


Далее в тексте, для удобства, вместо слова Mediastreamer2 будем использовать его русскую нотацию: "медиастример".


История его создания не совсем ясна, но судя по его исходному коду, он ранее использовал библиотеку Glib, что как бы намекает нам, на возможное дальнее родство с GStreamer. В сравнении с которым медиастример выглядит более легковесным. Первая версия Linphone появилась в 2001 году, так что в настоящий момент медиастример существует и развивается без малого 20 лет.


В основе медиастримера лежит архитектура называемая "Data flow" (поток данных). Пример такой архитектуры изображен на рисунке ниже.


Архитектура "Data flow"


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


Такая архитектура позволяет реализовать функционал обработки медиа в виде набора фильтров, соединенных в схему обработки и передачи RTP-трафика VoIP-телефона.


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


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


Звуковые фильтры


Захват и воспроизведение звука


  • Alsa (Linux): MS_ALSA_WRITE, MS_ALSA_READ
  • Android native sound (libmedia): MS_ANDROID_SOUND_WRITE, MS_ANDROID_SOUND_READ
  • Audio Queue Service (Mac OS X): MS_AQ_WRITE, MS_AQ_READ
  • Audio Unit Service (Mac OS X)
  • Arts (Linux): MS_ARTS_WRITE, MS_ARTS_READ
  • DirectSound (Windows): MS_WINSNDDS_WRITE, MS_WINSNDDS_READ
  • Проигрыватель файлов (raw/wav/pcap файлы) (Linux): MS_FILE_PLAYER
  • Проигрыватель файлов (raw/wav файлы) (Windows): MS_WINSND_READ
  • Запись в файл (wav файлы) (Linux): MS_FILE_REC
  • Запись в файл (wav файлы) (Windows): MS_WINSND_WRITE
  • Mac Audio Unit (Mac OS X)
  • MME (Windows)
  • OSS (Linux): MS_OSS_WRITE, MS_OSS_READ
  • PortAudio (Mac OS X)
  • PulseAudio (Linux): MS_PULSE_WRITE, MS_PULSE_READ
  • Windows Sound (Windows)

Кодирование/декодирование звука


  • G.711 a-закон: MS_ALAW_DEC, MS_ALAW_ENC
  • G.711 µ-закон: MS_ULAW_DEC, MS_ULAW_ENC
  • G.722: MS_G722_DEC, MS_G722_ENC
  • G.726: MS_G726_32_ENC, MS_G726_24_ENC, MS_G726_16_ENC
  • GSM: MS_GSM_DEC, MS_GSM_ENC
  • Линейная ИКМ: MS_L16_ENC, MS_L16_DEC
  • Speex: MS_SPEEX_ENC, MS_SPEEX_DEC

Обработка звука


  • Преобразование канала (моно->стерео, стерео->моно): MS_CHANNEL_ADAPTER
  • Конференция: MS_CONF
  • Генератор DTMF: MS_DTMF_GEN
  • Подавление эха (speex): MS_SPEEX_EC
  • Эквалайзер: MS_EQUALIZER
  • Микшер: MS_MIXER
  • Компенсатор потери пакетов (PLC): MS_GENERIC_PLC
  • Ресемплер: MS_RESAMPLE
  • Детектор тонов: MS_TONE_DETECTOR
  • Управление громкостью и измерение уровня сигнала: MS_VOLUME

Фильтры видео


Захват и воспроизведение видео


  • Android захват
  • Android воспроизведение
  • AV Foundation захват (iOS)
  • AV Foundation воспроизведение (iOS)
  • DirectShow захват (Windows)
  • DrawDib воспроизведение (Windows)
  • External воспроизведение — Отправка видео на верхний уровень
  • GLX воспроизведение (Linux): MS_GLXVIDEO
  • Mire — Synthetic moving picture: MS_MIRE
  • OpenGL воспроизведение (Mac OS X)
  • OpenGL ES2 воспроизведение (Android)
  • Quicktime захват (Mac OS X)
  • SDL воспроизведение: MS_SDL_OUT
  • Вывод статических изображений: MS_STATIC_IMAGE
  • Video For Linux (V4L) захват (Linux): MS_V4L
  • Video For Linux 2 (V4L2) захват (Linux): MS_V4L2_CAPTURE
  • Video4windows (DirectShow) захват (Windows)
  • Video4windows (DirectShow) захват (Windows CE)
  • Video For Windows (vfw) захват (Windows)
  • XV воспроизведение (Linux)

Кодирование/декодирование видео


  • H.263, H.263-1998, MP4V-ES, JPEG, MJPEG, Snow: MS_MJPEG_DEC, MS_H263_ENC, MS_H263_DEC
  • H.264 (только декодер): MS_H264_DEC
  • Theora: MS_THEORA_ENC, MS_THEORA_DEC
  • VP8: MS_VP8_ENC, MS_VP8_DEC

Обработка видео


  • JPEG snapshot
  • Pixel format converter: MS_PIX_CONV
  • Ресайзер
  • Другие фильтры
  • Обмен блоками данных между тредами: MS_ITC_SOURCE, MS_ITC_SINK
  • Сбор блоков данных с нескольких входов на один выход: MS_JOIN
  • RTP прием/передача: MS_RTP_SEND, MS_RTP_RECV
  • Копирование входных данных на несколько выходов: MS_TEE
  • Согласованная нагрузка: MS_VOID_SINK
  • Источник тишины: MS_VOID_SOURCE

Плагины


Звуковые фильтры


  • AMR-NB кодер/декодер


  • G.729 кодер/декодер


  • iLBC кодер/декодер


  • SILK кодер/декодер


    Фильтры видео


  • H.264 программный кодер


  • H.264 V4L2 кодер/декодер с аппаратным ускорением



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


Установка под Linux Ubuntu


Теперь мы выполним установку медиастримера на компьютер и соберем наше первое приложение с ним.


Установка Mediastremer2 на компьютер или виртуальную машину под управлением Ubuntu не требует особых навыков. Здесь и далее символом "$" будем обозначать приглашение оболочки shell для ввода команд. Т.е. если в листинге вы видите этот символ в начале строки, то значит это строка в которой показаны команды для выполнения в терминале.


Предполагается, что во время выполнения действий описанных в этой статье, ваш компьютер имеет доступ к сети Интернет.


Установка пакета libmediastremer-dev


Запускаем терминал и набираем команду:


$ sudo apt-get update

Будет запрошен пароль на внесение изменений, введите его и менеджер пакетов обновит свои базы. После этого нужно выполнить:


$ sudo apt-get install libmediastreamer-dev

Будут автоматически скачаны и установлены необходимые пакеты зависимостей и сама библиотека медиастримера.


Общий размер скачанных deb-пакетов зависимостей составит примерно 35 МБайт. Подробности об установленном пакете можно узнать командой:


$ dpkg -s libmediastreamer-dev

Пример ответа:


Package: libmediastreamer-dev
Status: install ok installed
Priority: optional
Section: libdevel
Installed-Size: 244
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Source: linphone
Version: 3.6.1-2.5
Depends: libmediastreamer-base3 (= 3.6.1-2.5), libortp-dev
Description: Linphone web phone's media library - development files
Linphone is an audio and video internet phone using the SIP protocol. It
has a GTK+ and console interface, includes a large variety of audio and video
codecs, and provides IM features.
.
This package contains the development libraries for handling media operations.
Original-Maintainer: Debian VoIP Team <pkg-voip-maintainers@lists.alioth.debian.org>
Homepage: http://www.linphone.org/

Установка инструментов разработки


Устанавливаем компилятор Си и сопутствующие ему инструменты:


$ sudo apt-get install gcc

Проверяем результат, запросив версию компилятора:


$ gcc --version

Ответ должен быть примерно таким:


gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Сборка и запуск пробного приложения


Создаем в home папку для наших учебных проектов, назовем её mstutorial:


$ mkdir ~/mstutorial

Воспользуйтесь вашим любимым текстовым редактором и создайте файл Си-программы с именем mstest.c со следующим содержанием:


#include "stdio.h"
#include <mediastreamer2/mscommon.h>
int main()
{
  ms_init();
  printf ("Mediastreamer is ready.\n");
}

Она выполняет инициализацию медиастримера, печатает приветствие и заканчивает выполнение.


Сохраняем файл и компилируем тестовое приложение командой:


$ gcc mstest.c -o mstest `pkg-config mediastreamer --libs --cflags`

Обратите внимание, что строка


`pkg-config mediastreamer --libs --cflags`

заключена в кавычки, которые находятся на клавиатуре там же где и буква "Ё".


Если файл не содержит ошибок, то после компиляции в каталоге появится файл mstest. Запускаем программу:


$ ./mstest

Результат будет таким:


ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib control.c:954:(snd_ctl_open_noupdate) Invalid CTL default:0
ortp-warning-Could not attach mixer to card: Invalid argument
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ALSA lib conf.c:4738:(snd_config_expand) Unknown parameters 0
ALSA lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM default:0
ortp-warning-Strange, sound card HDA Intel PCH does not seems to be capable of anything, retrying with plughw...
Mediastreamer is ready.

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


Теперь у нас все готово для работы с медиастримером. Мы установили библиотеку медиастримера, инструмент компиляции и с помощью пробного приложения проверили, что инструменты настроены, а медиастример успешно инициализируется.


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