Материал статьи взят с моего дзен-канала.
Введение
Эта статья является началом серии статей о реалтайм обработке медиаданных с помощью движка 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, она используется для управления звуковой картой. Сами разработчики медиастримера считают, что это нормально. Мы в данном случае по неволе согласимся с ними.
Теперь у нас все готово для работы с медиастримером. Мы установили библиотеку медиастримера, инструмент компиляции и с помощью пробного приложения проверили, что инструменты настроены, а медиастример успешно инициализируется.
В следующей статье мы создадим приложение, которое соберет и запустит обработку звукового сигнала в цепочке из нескольких фильтров.