Материал статьи взят с моего дзен-канала.
Введение
Эта статья является началом серии статей о реалтайм обработке медиаданных с помощью движка Mediastreamer2. В ходе изложения будут задействованы минимальные навыки работы в терминале Linux и программирования на языке Си.
Mediastreamer2 это VoIP-движок, лежащий в основе популярного open-source проекта программного voip-телефона Linphone. В Linphone Mediastreamer2 реализует все функции связанные со звуком и видео. Подробный список возможностей движка можно увидеть на этой странице Mediastreamer. Исходный код находится здесь: GitLab.
Далее в тексте, для удобства, вместо слова Mediastreamer2 будем использовать его русскую нотацию: "медиастример".
История его создания не совсем ясна, но судя по его исходному коду, он ранее использовал библиотеку Glib, что как бы намекает нам, на возможное дальнее родство с GStreamer. В сравнении с которым медиастример выглядит более легковесным. Первая версия Linphone появилась в 2001 году, так что в настоящий момент медиастример существует и развивается без малого 20 лет.
В основе медиастримера лежит архитектура называемая "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, она используется для управления звуковой картой. Сами разработчики медиастримера считают, что это нормально. Мы в данном случае по неволе согласимся с ними.
Теперь у нас все готово для работы с медиастримером. Мы установили библиотеку медиастримера, инструмент компиляции и с помощью пробного приложения проверили, что инструменты настроены, а медиастример успешно инициализируется.
В следующей статье мы создадим приложение, которое соберет и запустит обработку звукового сигнала в цепочке из нескольких фильтров.